public class SherpaSettings {

	private static Logger LOGGER = LoggerFactory.getLogger(SherpaSettings.class);
	
	public static final String SETTINGS_SHERPA_CONTEXT = "com.khs.sherpa.SETTINGS_SHERPA_CONTEXT";
	public static final String SETTINGS_SERVER_URL = "com.khs.sherpa.SETTINGS_SERVER_URL";
	public static final String SETTINGS_SERVER_TOKEN = "com.khs.sherpa.SETTINGS_SERVER_TOKEN";
	
	protected Properties properties;
	
	public SherpaSettings(String configFile) {
		
		try {
			
			InputStream in = null;
			if(configFile.startsWith("classpath:")) {
				in = SherpaServlet.class.getClassLoader().getResourceAsStream(configFile.substring("classpath:".length()));
			} else {
				in = new FileInputStream(configFile);
			}
		    if (in != null) {
		    	properties = new Properties();
		    	properties.load(in);
		    	LOGGER.info(msg("sherpa properties loaded"));
			}
		} catch (IOException e) {
			LOGGER.error("sherpa properties not found, defaults applied...");
         // does'nt exist...
		}
		
		if (properties == null) {			
			throw new RuntimeException(SHERPA_NOT_INITIALIZED+"property file sherpa.properties must be defined in classpath");
		}
	}
	
	
	public SherpaSettings(Properties properties) {
		this.properties = properties;
	}
	
	public String sherpaAdmin() {
	    String value = properties.getProperty("sherpa.role");
		if (value != null) {
			return value;
		} 
		return Defaults.SHERPA_ADMIN;
	}
	
	public String encoding() {
	    String value = properties.getProperty("encode.format");
		if (value != null) {
			value = value.toUpperCase();
			if (value.equals(Encode.CSV) || value.equals(Encode.XML) || value.equals(Encode.HTML)) {
				return value;
			}		
		}
		return Defaults.ENCODE;
	}
	
	public boolean logging() {
	    String value = properties.getProperty("activity.logging");
		if (value != null) {
			value = value.toUpperCase();
			if (value.equalsIgnoreCase("N") || value.equalsIgnoreCase("NO") || value.equalsIgnoreCase("FALSE")) {
				return false;
			}		
		} 
		return Defaults.ACTIVITY_LOG;
	}
	
	public boolean endpointAuthenication() {
		String value = properties.getProperty("endpoint.authentication");
		if(value != null) {
			if (value.equalsIgnoreCase("Y") || value.equalsIgnoreCase("YES") || value.equalsIgnoreCase("TRUE")) {
				return true;
			}	
		}
		return Defaults.ENDPOINT_AUTHENTICATION;
	}
	
	public boolean jsonpSupport() {
	    String value = properties.getProperty("jsonp.support");
		if (value != null) {
			value = value.toUpperCase();
			if (value.equalsIgnoreCase("Y") || value.equalsIgnoreCase("YES") || value.equalsIgnoreCase("TRUE")) {
				return true;
			}		
		} 
		return Defaults.JSONP_SUPPORT;
	}
	
	
	public String dateFormat() {
		String value = properties.getProperty("date.format");
		if (value != null) {
			return value;		
		}
		return Defaults.DATE_FORMAT;
	}
	
	public String dateTimeFormat() {
		String value = properties.getProperty("date.time.format");
		if (value != null) {
			return value;		
		}
		return Defaults.DATE_TIME_FORMAT;
	}
	
	public long timeout() {
		String value = properties.getProperty("session.timeout");
		if (value != null) {
			try {
				long timeout = Long.parseLong(value);
				LOGGER.info(msg("session timeout set to "+timeout+" ms"));
				return timeout;
				
			} catch(NumberFormatException e) {
				throw new RuntimeException("ERROR reading session.timeout value from property file, value must be long");
			}
		}
		LOGGER.info(msg("session timeout set to "+Defaults.SESSION_TIMEOUT+" ms"));
		return Defaults.SESSION_TIMEOUT;
	}
	
	public Class<?> jsonProvider() {
		String userClazzName = properties.getProperty("json.provider");
		if (userClazzName == null) {
			return GsonJsonProvider.class;
		} else {
			return getInstanceClass(userClazzName);
		}
	}
	
	public String endpoint() {
		String endpoint = properties.getProperty("endpoint.package");
		if (endpoint != null) {
			int end = endpoint.length();
			// add package separator
			if (endpoint.lastIndexOf('.') != end - 1) {
				endpoint += ".";
			}
		} else {			
			throw new RuntimeException(SHERPA_NOT_INITIALIZED+"endpoint package location must be defined in sherpa.properties");		
		}
		return endpoint;
	}

	public Class<?> applicationContext() {
		String applicationContextName = properties.getProperty("application.context");
		if (applicationContextName == null) {
			return null;
		} else {
			return getInstanceClass(applicationContextName);
		}
	}

	public Class<?> userService() {
		String userClazzName = properties.getProperty("user.service");
		if (userClazzName == null) {
			try {
				return Class.forName("com.khs.sherpa.spring.SpringAuthentication");
			} catch (ClassNotFoundException e1) {
				return DefaultUserService.class;
			}
			
		} else {
			return getInstanceClass(userClazzName);
		}
	}

	public Class<?> sherpaRequestService() {
		String tokenClazzName = properties.getProperty("request.service");
		if (tokenClazzName == null) {
			try {
				return Class.forName("com.khs.sherpa.spring.DefaultSpringSherpaRequest");
			} catch (ClassNotFoundException e) {
				return DefaultSherpaRequest.class;
			}
		} else {
			return getInstanceClass(tokenClazzName);
		}
	}

	public Class<?> tokenService() {
		String tokenClazzName = properties.getProperty("token.service");
		if (tokenClazzName == null) {
			return DefaultTokenService.class;
		} else {
			return getInstanceClass(tokenClazzName);
		}
	}
	
	public Class<?> activityService() {
		String activityClazzName = properties.getProperty("activity.service");
		if (activityClazzName == null) {
			return DefaultActivityService.class;
		} else {
			return getInstanceClass(activityClazzName);
		}
	}
	
	public String serverToken() {
		String value = properties.getProperty("server.token");
		if(StringUtils.isNotEmpty(value)) {
			return value;
		}
		return null;
	}
	
	public String serverUrl() {
		String value = properties.getProperty("server.url");
		if(!StringUtils.isEmpty(value)) {
			// always remove the ending /
			if(StringUtils.endsWith(value, "/")) {
				value = StringUtils.removeEnd(value, "/");
			}
			return value;
		}
		return null;
	}
	
	protected Class<?> getInstanceClass(String name) {
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("User service class not found " + name);
		}
	}
	
	protected Object createInstance(String name) {
		try {
			Class<?> clazz = Class.forName(name);
			return clazz.newInstance();

		} catch (ClassNotFoundException e) {
			throw new RuntimeException("User service class not found " + name);
		} catch (InstantiationException e) {
			throw new RuntimeException("User service class could be instantiated " + name);
		} catch (IllegalAccessException e) {
			throw new RuntimeException("User service class could not be accessed " + name);
		}

	}

} public class NoSuchManagedBeanExcpetion extends SherpaException {

	public NoSuchManagedBeanExcpetion() {
		super();
	}

	public NoSuchManagedBeanExcpetion(String arg0, Throwable arg1) {
		super(arg0, arg1);
	}

	public NoSuchManagedBeanExcpetion(String arg0) {
		super(arg0);
	}

	public NoSuchManagedBeanExcpetion(Throwable arg0) {
		super(arg0);
	}

	private static final long serialVersionUID = 3764129759598703541L;

} public class BooleanParamParser implements ParamParser<Boolean> {

	public boolean isValid(Class<?> clazz) {
		return (clazz.isAssignableFrom(Boolean.class) || clazz.isAssignableFrom(boolean.class));
	}

	public Boolean parse(String value, Param annotation, Class<?> clazz) {
		return Boolean.parseBoolean(value);
	}

} public class CalendarParamParser implements ApplicationContextAware, ParamParser<Calendar> {

	public static final String DEFAULT = "com.khs.sherpa.DEFUALT_CALENDAR_FORMAT";
	
	private ApplicationContext applicationContext;
	
	public boolean isValid(Class<?> clazz) {
		return clazz.isAssignableFrom(Calendar.class);
	}

	public Calendar parse(String value, Param annotation, Class<?> clazz) {
		String format = annotation.format();
		if(format == null) {
			format = (String) applicationContext.getAttribute(DEFAULT);
		}
		
		try {
			DateFormat fmt = new SimpleDateFormat(format);
			Calendar cal = Calendar.getInstance();
			cal.setTime(fmt.parse(value));
			return cal;
		} catch (ParseException e) {
			throw new RuntimeException(value+" must be calender ");
		}
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

} public class DateParamParser implements ApplicationContextAware, ParamParser<Date> {

	public static final String DEFAULT = "com.khs.sherpa.DEFUALT_DATE_FORMAT";
	
	private ApplicationContext applicationContext;
	
	public boolean isValid(Class<?> clazz) {
		return clazz.isAssignableFrom(Date.class);
	}

	public Date parse(String value, Param annotation, Class<?> clazz) {
		String format = annotation.format();
		if(format == null || format.equals("")) {
			format =  (String) applicationContext.getAttribute(DEFAULT);
		}
		
		try {
			DateFormat fmt = new SimpleDateFormat(format);
			return fmt.parse(value);
		} catch (ParseException e) {
			throw new RuntimeException(value+" must be date ");
		}
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

} public class DoubleParamPaser implements ParamParser<Double> {

	public boolean isValid(Class<?> clazz) {
		return (clazz.isAssignableFrom(Double.class) || clazz.isAssignableFrom(double.class));
	}

	public Double parse(String value, Param annotation, Class<?> clazz) {
		try {
			return Double.parseDouble(value);
		} catch (NumberFormatException e) {
			throw new RuntimeException(value+" must be double ");
		}
	}

} public class FloatParamParser implements ParamParser<Float> {

	public boolean isValid(Class<?> clazz) {
		return (clazz.isAssignableFrom(float.class) || clazz.isAssignableFrom(Float.class));
	}

	public Float parse(String value, Param annotation, Class<?> clazz) {
		try {
			return Float.parseFloat(value);
		} catch (NumberFormatException e) {
			throw new RuntimeException(value+" must be float ");
		}
	}

} public class IntegerParamParser implements ParamParser<Integer> {

	public boolean isValid(Class<?> clazz) {
		return (clazz.isAssignableFrom(Integer.class) || clazz.isAssignableFrom(int.class));
	}

	public Integer parse(String value, Param annotation, Class<?> clazz) {
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			throw new RuntimeException(value+" must be integer ");
		}
	}


} public class JsonParamParser implements ApplicationContextAware, ParamParser<Object> {

	private JsonProvider jsonProvider;
	
	public boolean isValid(Class<?> clazz) {
		return !clazz.isAssignableFrom(Boolean.class) && 
				!clazz.isAssignableFrom(boolean.class) &&
				!clazz.isAssignableFrom(Calendar.class) &&
				!clazz.isAssignableFrom(Date.class) &&
				!clazz.isAssignableFrom(Double.class) &&
				!clazz.isAssignableFrom(double.class) &&
				!clazz.isAssignableFrom(float.class) &&
				!clazz.isAssignableFrom(Float.class) &&
				!clazz.isAssignableFrom(Integer.class) &&
				!clazz.isAssignableFrom(int.class) &&
				!clazz.isAssignableFrom(Integer.class) && 
				!clazz.isAssignableFrom(int.class);
	}

	public Object parse(String value, Param annotation, Class<?> clazz) {
		return jsonProvider.toObject(value, clazz);
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		try {
			this.jsonProvider = applicationContext.getManagedBean(JsonProvider.class);
		} catch (NoSuchManagedBeanExcpetion e) {
			e.printStackTrace();
		}
	}
	
} public class StringParamParser implements ApplicationContextAware, ParamParser<String> {
	
	public static final String DEFAULT = "com.khs.sherpa.DEFUALT_STRING_FORMAT";
	
	private ApplicationContext applicationContext;
	
	public String parse(String value, Param annotation, Class<?> clazz) {
		String format = annotation.format();
		
		if(format == null || format.equals("")) {
			format = (String) applicationContext.getAttribute(DEFAULT);
		}
		
		return this.applyEncoding(value, format);
	}

	public boolean isValid(Class<?> clazz) {
		return clazz.isAssignableFrom(String.class);
	}

	private String applyEncoding(String value,String format) {
		String result = value;
		if (format != null) {
			if (format.equals(Encode.XML)) {
				result = StringEscapeUtils.escapeXml(value);		
			} else if (format.equals(Encode.HTML)) {
				result = StringEscapeUtils.escapeHtml4(value);		
			} else if (format.equals(Encode.CSV)) {
				result = StringEscapeUtils.escapeCsv(value);
			}
		}
		  
		return result;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import org.reflections.Reflections;
import com.khs.sherpa.SherpaSettings;
import com.khs.sherpa.annotation.Endpoint;
import com.khs.sherpa.exception.NoSuchManagedBeanExcpetion;
import com.khs.sherpa.parser.BooleanParamParser;
import com.khs.sherpa.parser.CalendarParamParser;
import com.khs.sherpa.parser.DateParamParser;
import com.khs.sherpa.parser.DoubleParamPaser;
import com.khs.sherpa.parser.FloatParamParser;
import com.khs.sherpa.parser.IntegerParamParser;
import com.khs.sherpa.parser.JsonParamParser;
import com.khs.sherpa.parser.StringParamParser;
package com.khs.sherpa.context.factory;

/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */





public class DefaultManagedBeanFactory implements ManagedBeanFactory, InitManageBeanFactory {

	private Set<ManagedBean> managedBeans = new LinkedHashSet<ManagedBean>();
	
	public boolean containsManagedBean(Class<?> type) {
		for(ManagedBean bean: managedBeans) {
			if(type.isAssignableFrom(bean.getType())) {
				return true;
			}
		}
		return false;
	}

	public boolean containsManagedBean(String name) {
		for(ManagedBean bean: managedBeans) {
			if(bean.getName().equals(name)) {
				return true;
			}
		}
		return false;
	}

	public <T> T getManagedBean(Class<T> type) throws NoSuchManagedBeanExcpetion {
		for(ManagedBean bean: managedBeans) {
			if(type.isAssignableFrom(bean.getType())) {
				return (T) bean.getInstance();
			}
		}
		throw new NoSuchManagedBeanExcpetion(type.getName());
	}

	public <T> Collection<T> getManagedBeans(Class<T> type) {
		List<T> list = new ArrayList<T>();
		for(ManagedBean bean: managedBeans) {
			if(type.isAssignableFrom(bean.getType())) {
				list.add((T)bean.getInstance());
			}
		}
		return list;
	}
	
	public Object getManagedBean(String name) throws NoSuchManagedBeanExcpetion {
		for(ManagedBean bean: managedBeans) {
			if(bean.getName().equals(name)) {
				return bean.getInstance();
			}
		}
		throw new NoSuchManagedBeanExcpetion(name);
	}

	public <T> T getManagedBean(String name, Class<T> type) throws NoSuchManagedBeanExcpetion {
		return (T) this.getManagedBean(name);
	}

	public boolean isTypeMatch(String name, Class<?> type) throws NoSuchManagedBeanExcpetion {
		return this.getType(name).isAssignableFrom(type);
	}

	public Class<?> getType(String name) throws NoSuchManagedBeanExcpetion {
		return this.getManagedBean(name).getClass();
	}

	public int managedBeansCount() {
		return managedBeans.size();
	}
	
	public void loadManagedBeans(String path) {
		Reflections reflections = new Reflections(path);
		this.loadManagedBeans(reflections.getTypesAnnotatedWith(com.khs.sherpa.annotation.Endpoint.class));
	}
	
	public void loadManagedBeans(Set<Class<?>> types) {
		for(Class<?> type: types) {
			this.loadManagedBean(type);
		}
	}
	
	public void loadManagedBean(Class<?> type) {
		ManagedBean bean = new ManagedSingletonBean(type);
		managedBeans.add(bean);
	}

	public Map<String, Object> getEndpointTypes() {
		Map<String, Object> map = new HashMap<String, Object>();
		for(ManagedBean bean: managedBeans) {
			if(bean.getType().isAnnotationPresent(Endpoint.class)) {
				map.put(bean.getName(), bean.getInstance());
			}
		}
		return map;
	}

	public void init(SherpaSettings settings, ServletContext context) {