/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.cologneintelligence.fitgoodies.database.dynamic;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.FieldGen;
import org.apache.bcel.generic.Type;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;

/**
 * Factory that allows to generate java classes on the fly.
 * The class will have a public constructor and only public variables.
 * <p>
 * This class is primary written for internal use.
 */
public class DynamicObjectFactory {
	/**
	 * Class loader which is able to load the dynamic generated class.
	 *
	 * @author jwierum
	 */
	public static class JavaClassClassloader extends java.lang.ClassLoader {
		/**
		 * Default constructor. Creates a new {@code ClassLoader}.
		 */
		public JavaClassClassloader() {
			super(JavaClassClassloader.class.getClassLoader());
		}

		@Override
		public final Class<?> loadClass(final String name)
				throws ClassNotFoundException {
			if (cache.containsKey(name)) {
				return cache.get(name);
			} else {
				return super.loadClass(name);
			}
		}

		private final HashMap<String, Class<?>> cache = new HashMap<>();

		/**
		 * Loads the byte code of {@code javaClass}, defines a class
		 * and resolves it. The loaded class is returned.
		 *
		 * @param name      class name
		 * @param javaClass {@code JavaClass} object which holds the
		 *                  dynamically generated class.
		 * @return the loaded class
		 */
		public final Class<?> loadJavaClass(final String name,
		                                    final JavaClass javaClass) {
			byte[] binClass = javaClass.getBytes();

			Class<?> c = defineClass(javaClass.getClassName(),
					binClass, 0, binClass.length);

			resolveClass(c);
			cache.put(name, c);
			return c;
		}
	}

	private final ClassGen cg;
	private Class<?> result;
	private static int classCount = 1;
	private static JavaClassClassloader loader;

	static {
		loader = AccessController.doPrivileged(
				new PrivilegedAction<JavaClassClassloader>() {
					@Override
					public JavaClassClassloader run() {
						return new JavaClassClassloader();
					}
				});
	}

	/**
	 * Default constructor. Prepares a new class.
	 */
	public DynamicObjectFactory() {
		cg = new ClassGen(
				"$DynamicGeneratedObject$" + classCount,
				"java.lang.Object", "<generated>",
				Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
		++classCount;
		cg.addEmptyConstructor(Constants.ACC_PUBLIC);
	}

	/**
	 * Adds a public field to the constructed class.
	 *
	 * @param type type of the field
	 * @param name name of the field
	 * @throws ClassNotFoundException indicates a problem with {@code type}
	 */
	public void add(final Class<?> type, final String name) throws ClassNotFoundException {
		FieldGen fg;

		if (result != null) {
			throw new IllegalStateException("Class already generated");
		}

		fg = new FieldGen(Constants.ACC_PUBLIC | Constants.ACC_SUPER,
				Type.getType(type), name, cg.getConstantPool());
		cg.addField(fg.getField());
	}

	/**
	 * Compiles the class and returns a class object which contains all
	 * added fields.
	 *
	 * @return dynamic generated class with all added fields.
	 */
	public final Class<?> compile() {
		if (result == null) {
			loader.loadJavaClass(cg.getClassName(), cg.getJavaClass());
			try {
				result = loader.loadClass(cg.getClassName());
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
		}
		return result;
	}
}


package js.http.captcha;

import java.io.File;
import java.io.FileFilter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import js.util.Strings;

/**
 * A challenge has a random set of images and a value related to one image from set. One from these images is the correct
 * challenge response. It is sent to client that displays images and value allowing the user to select the right image.
 *

 * Implementation note: Challenge instance is loaded by client script. Fields {@link #images} and {@link #value} are known to
 * script logic by name and should not be changed.
 *
 * @author Iulian Rotaru
 * @version final
 */
public final class Challenge implements Serializable {
	/** Java serialization version. */
	private static final long serialVersionUID = -6867379696435211853L;

	/** Constant for CAPTCHA resource URL. */
	private static final String RESOURCE_URL = "captcha/image?";

	/** Random generator for images set. Selects random images from images repository provided to constructor. */
	private transient final Random randomImageGenerator = new Random();

	/**
	 * Random generator for challenge value. It is used to choose a random image from images set and compute challenge value
	 * based on image file name, see {@link #getValue(File)}.
	 */
	private transient final Random randomValueGenerator = new Random();

	/** Current challenge set of tokens mapped to related image files, from images repository given to constructor. */
	private transient final Map<String, File> tokenedImageFiles;

	/**
	 * Images set stored as relative URL with token request parameter. Image URL is based on {@link #RESOURCE_URL}. Every image
	 * from this challenge images set is identified by an unique URL.
	 *

	 * This field is visible on client script with this specific name.
	 */
	private final List<String> images;

	/**
	 * Challenge value. This value is displayed to user as a hint related to one of {@link #images}. This field is visible on
	 * client script with this specific name.
	 */
	private final String value;

	/**
	 * Create challenge instance and initialize it from given images repository and with requested set size. Set size is a hint
	 * and client should not rely on its value but use {@link #images} size instead.
	 *

	 * Images repository should contain only images related to CAPTCHA. All files are considered candidates for challenge set.
	 * Sub-directories are not included.
	 *
	 * @param repository images repository,
	 * @param setSize challenge images set size.
	 */
	public Challenge(File repository, int setSize) {
		this.images = new ArrayList<>(setSize);
		this.tokenedImageFiles = new HashMap<>(setSize);

		// loads random images from repository
		// Random.nextInt(int) has an approximative uniform distribution and with very unlikely probability can return the same
		// image file index multiple times
		// in such cases returned images set is smaller than requested set size

		// skip sub-directories from images repository scanning
		File[] files = repository.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				return pathname.isFile();
			}
		});

		Set<File> filesSet = new HashSet<>(setSize);
		while (filesSet.size() < setSize) {
			filesSet.add(files[this.randomImageGenerator.nextInt(files.length)]);
		}

		this.images.clear();
		this.tokenedImageFiles.clear();
		for (File file : filesSet) {
			String token = Strings.UUID();
			this.images.add(RESOURCE_URL + token);
			this.tokenedImageFiles.put(token, file);
		}

		List<File> values = new ArrayList<>(this.tokenedImageFiles.values());
		this.value = getValue(values.get(this.randomValueGenerator.nextInt(setSize)));
	}

	/**
	 * Get image file related to given unique token.
	 *
	 * @param token unique token, null or empty tolerated.
	 * @return image file or null if not registered token.
	 */
	public File getImage(String token) {
		return tokenedImageFiles.get(token);
	}

	/**
	 * Test that selected image identified by given token is the right response.
	 *
	 * @param token unique token identifying selected image, null or empty tolerated.
	 * @return true if token identifies this challenge response.
	 */
	public boolean verifyResponse(String token) throws NullPointerException {
		return value.equals(getValue(tokenedImageFiles.get(token)));
	}

	/** Regular expression constant for file extension. */
	private static final String EXTENSION_REX = "\\.[^.]+$";

	/** Regular expression constant for not letters characters used as words separator. */
	private static final String NOT_LETTERS_REX = "[^a-z]+";

	/**
	 * Challenge value associated with image file. File name is converted to lower case, extension removed and non letter
	 * characters replaces with space, that is, non letters are considered words separators.
	 *
	 * @param file image file, null tolerated.
	 * @return challenge value or null if given file is null.
	 */
	private static String getValue(File file) throws NullPointerException {
		if (file == null) {
			return null;
		}
		return file.getName().toLowerCase().replaceAll(EXTENSION_REX, "").replaceAll(NOT_LETTERS_REX, " ");
	}
}


package net.typedrest;

import java.net.*;
import lombok.SneakyThrows;
import org.apache.http.client.utils.URIBuilder;

/**
 * Provides utility methods for {@link URI}.
 */
public final class URIUtils {

    private URIUtils() {
    }

    /**
     * Adds a trailing slash to the URI if it does not already have one.
     *
     * @param uri The original URI.
     * @return The URI with appended slash.
     */
    @SneakyThrows
    public static URI ensureTrailingSlash(URI uri) {
        URIBuilder builder = new URIBuilder(uri);
        if (!builder.getPath().endsWith("/")) {
            builder.setPath(builder.getPath() + "/");
        }
        return builder.build();
    }
}


/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
*/

package de.cologneintelligence.fitgoodies.mail;

import java.util.Properties;

/**
 * Singleton class that holds information on how to access mails.
 * Can be set via HTML using the {@link SetupFixture}.
 */
public final class SetupHelper {
	private String user;
	private String pass;
	private String proto;
	private String host;
	private String inbox;
	private boolean ssl;
	private int port;

	private void setProperty(final Properties prop,
	                         final String name, final String value) {
		if (value != null) {
			prop.setProperty(name, value);
		}
	}

	/**
	 * Generates a properties object which can be used by
	 * {@link de.cologneintelligence.fitgoodies.mail.providers.JavaMailMessageProvider}.
	 * Default values are not set.
	 *
	 * @return properties object
	 */
	public Properties generateProperties() {
		Properties result = new Properties();

		if (proto == null) {
			throw new RuntimeException("no protocol selected");
		}

		String protocol = proto.toLowerCase();

		setProperty(result, "mail.store.protocol", protocol);
		setProperty(result, "mail." + protocol + ".host", host);
		setProperty(result, "mail.username", user);
		setProperty(result, "mail.password", pass);

		if (port != 0) {
			setProperty(result, "mail." + protocol + ".port", Integer.toString(port));
		}

		if (ssl) {
			setProperty(result, "mail." + protocol + ".ssl", "true");
		}

		if (protocol.equals("pop3")) {
			setProperty(result, "mail.inbox", "INBOX");
		} else {
			if (inbox == null) {
				throw new RuntimeException("no inbox selected");
			}

			setProperty(result, "mail.inbox", inbox);
		}

		return result;
	}

	/**
	 * Sets the protocol to use.
	 *
	 * @param protocol protocol to use
	 */
	public void setProtocol(final String protocol) {
		proto = protocol;
	}

	/**
	 * Sets the user name to use.
	 *
	 * @param username user name to use
	 */
	public void setUsername(final String username) {
		user = username;
	}

	/**
	 * Sets the password to use.
	 *
	 * @param password the password to use
	 */
	public void setPassword(final String password) {
		pass = password;
	}

	/**
	 * Sets the hostname to use.
	 *
	 * @param hostname hostname to use
	 */
	public void setHost(final String hostname) {
		host = hostname;
	}

	/**
	 * Sets the inbox to use.
	 *
	 * @param inboxname inbox to use
	 */
	public void setInbox(final String inboxname) {
		inbox = inboxname;
	}

	/**
	 * Sets whether SSL will be used.
	 *
	 * @param enable sets the SSL state
	 */
	public void setSSL(final boolean enable) {
		ssl = enable;
	}

	/**
	 * Sets the port that will be used.
	 *
	 * @param port port to use
	 */
	public void setPort(final int port) {
		this.port = port;
	}
}


package js.servlet;

import java.io.File;
import java.security.Principal;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import js.container.Container;
import js.container.InstanceScope;
import js.converter.ConverterRegistry;
import js.core.AppContext;
import js.core.Factory;
import js.core.SecurityContext;
import js.lang.BugError;
import js.lang.Config;
import js.lang.ConfigBuilder;
import js.lang.ConfigException;
import js.log.Log;
import js.log.LogContext;
import js.log.LogFactory;
import js.util.Strings;

/**
 * Container specialization for web applications. This class extends {@link Container} adding implementation for
 * {@link InstanceScope#SESSION}, application context services and security context. Tiny container instance is accessible to
 * application code through {@link AppContext} interface.
 *

 * This class also implements {@link SecurityContext} services. For servlet container authentication this class delegates HTTP
 * request related services. For application provided authentication this class uses HTTP session to handle {@link Principal}
 * supplied via {@link #login(Principal)}.
 *
 *
Servlet Container Integration

 *

 * Servlet container creates and destroy tiny container instance via event listeners. This class implements both servlet context
 * and HTTP session event listeners and should be declared into application deployment descriptor.
 *
 *

 * <listener>
 * 	<listener-class>js.servlet.TinyContainer</listener-class>
 * </listener>
 *

 *

 * Event handlers manage tiny container life cycle. There is a single tiny container instance per web application created by
 * servlet container and initialized via {@link #contextInitialized(ServletContextEvent)} event handler. When web application is
 * unloaded tiny container is destroyed by {@link #contextDestroyed(ServletContextEvent)}. On first tiny container creation
 * takes care to initialize server global state. This class also track HTTP sessions creation and destroy for debugging.
 *
 *
Application Boostrap
 Here are overall steps performed by bootstrap logic. It is executed for every web application
 * deployed on server.
 *

 *
servlet container creates tiny container instance because is declared as listener on deployment descriptor,
 *
super-container and tiny container constructors are executed,
 *
servlet container invokes {@link #contextInitialized(ServletContextEvent)} on newly created tiny container instance,
 *
from now on logic is executed by above event handler:
 *
initialize {@link #contextParameters} from external descriptors,
 *
create {@link TinyConfigBuilder} that parses application descriptor,
 *
configure tiny container with created configuration object, see {@link #config(Config)},
 *
bind tiny container instance to master factory, see {@link Factory#bind(js.core.AppFactory)},
 *
finalize tiny container creation by calling {@link #start()}.
 *

 *

 * If tiny container is successfully configured and started, bootstrap logic stores its reference on servlet context attribute
 * {@link #ATTR_INSTANCE}. Anyway, if tiny container fails to start for some reason, dump stack trace and leave attribute null.
 * {@link AppServlet#init(javax.servlet.ServletConfig)} and {@link RequestPreprocessor#init(javax.servlet.FilterConfig)} test
 * tiny container attribute and if found null mark servlet as unavailable. This way a web application that fails to start tiny
 * container will have request preprocessor and all servlets unavailable and is not able to process any requests.
 *

 * Implementation note: It is assumed that {@link #contextInitialized(ServletContextEvent)} is invoked before any servlet
 * initialization via {@link AppServlet#init(javax.servlet.ServletConfig)}. Servlet specification does provide explicit evidence
 * for this prerequisite. Anyway there is something that can lead to this conclusion on section 10.12, see below; also found
 * support on API-DOC. Here is the relevant excerpt: All ServletContextListeners are notified of context initialization
 * before any filter or servlet in the web application is initialized.
 *
 *

 * For completeness here are web application deployment steps, excerpt from servlet specification 3.0, section 10.12:
 *

 *
Instantiate an instance of each event listener identified by a listener element in the deployment
 * descriptor.
 *
For instantiated listener instances that implement ServletContextListener, call the contextInitialized() method.
 *
Instantiate an instance of each filter identified by a filter element in the deployment descriptor and call
 * each filter instance’s init() method.
 *
Instantiate an instance of each servlet identified by a servlet element that includes a
 * load-on-startup element in the order defined by the load-onstartup element values, and call each servlet
 * instance’s init() method.
 *

 *
 * @author Iulian Rotaru
 * @version final
 */
public class TinyContainer extends Container implements ServletContextListener, HttpSessionListener, AppContext {
	/** Server global state and applications logger initialization. */
	private static final Server server = new Server();

	/** Class logger. */
	private static final Log log = LogFactory.getLog(TinyContainer.class);

	/** Container instance is stored on servlet context with this attribute name. */
	public static final String ATTR_INSTANCE = "js.servlet.WebContainer.instance";

	/** Session attribute name for principal storage when authentication is provided by application. */
	public static final String ATTR_PRINCIPAL = "js.servlet.WebContainer.principal";

	/** Name used for root context path. */
	public static final String ROOT_CONTEXT = "root";

	/** Diagnostic context name for context path, aka application. */
	private static final String LOG_CONTEXT_APP = "app";

	/**
	 * Server and container properties loaded from context parameters defined on external descriptors. Context parameters are
	 * optional and this properties instance can be empty. If present, context parameters are used by {@link TinyConfigBuilder}
	 * to inject variables. Also can be retrieved by application using {@link #getProperty(String)}.
	 *

	 * Tiny container uses {@link ServletContext#getInitParameter(String)} to load this context parameters. Context parameters
	 * source may depend on web server implementation but context-param from deployment descriptor is always
	 * supported.
	 */
	private final Properties contextParameters = new Properties();

	/** The name of web application that own this tiny container. Default value to test-app. */
	private String appName = "test-app";

	/**
	 * Application private storage. Privateness is merely a good practice rather than enforced by some system level rights
	 * protection. So called private directory is on working directory and has context name. Files returned by
	 * {@link #getAppFile(String)} are always relative to this private directory.
	 */
	private File privateDir;

	/**
	 * Optional login realm, default to web application context name. Basic authentication realm sent by servlets when client
	 * attempt to access non authorized resource.
	 *

	 * Basic authentication realm is loaded from application descriptor, login section. If not configured uses the
	 * context name.
	 *
	 *

	 * <login>
	 * 	<property name="realm" value="Fax2e-mail" />
	 * 	...
	 * </login>
	 *

	 */
	private String loginRealm;

	/**
	 * Location for application login page, null if not configured. This field value is loaded from application descriptor.
	 * Location can be relative or absolute to servlet container root, in which case starts with path separator. Container takes
	 * care to convert to absolute location if configured value is relative.
	 *
	 *

	 * Login page location is loaded from application descriptor, login section.
	 *
	 *

	 * <login>
	 * 	...
	 * 	<property name="page" value="index.htm" />
	 * </login>
	 *

	 *
	 *

	 * This login page location is an alternative to servlet container declarative form-login-page from
	 * login-config section from deployment descriptor. Anyway, if application has private resources accessed via
	 * XHR, this login page location is mandatory. Otherwise client agent default login form is used when XHR attempt to access
	 * not authorized resources.
	 */
	private String loginPage;

	/** Create tiny container instance. */
	public TinyContainer() {
		super();
		log.trace("TinyContainer()");
		registerScopeFactory(new SessionScopeFactory(this));
	}

	@Override
	protected void registerInstanceProcessor() {
		registerInstanceProcessor(new ContextParamProcessor(this));
		super.registerInstanceProcessor();
	}

	@Override
	protected void registerClassProcessor() {
		registerClassProcessor(new ContextParamProcessor(this));
		super.registerClassProcessor();
	}

	@Override
	public void config(Config config) throws ConfigException {
		super.config(config);

		// by convention configuration object name is the web application name
		appName = config.getName();

		privateDir = server.getAppDir(appName);
		if (!privateDir.exists()) {
			privateDir.mkdir();
		}

		Config loginConfig = config.getChild("login");
		if (loginConfig != null) {
			loginRealm = loginConfig.getProperty("realm", appName);
			loginPage = loginConfig.getProperty("page");
			if (loginPage != null && !loginPage.startsWith("/")) {
				loginPage = Strings.concat('/', appName, '/', loginPage);
			}
		}
	}

	// --------------------------------------------------------------------------------------------
	// SERVLET CONTAINER LISTENERS

	/**
	 * Implements tiny container boostrap logic. See class description for overall performed steps. Also loads context
	 * parameters from external descriptors using {@link ServletContext#getInitParameter(String)}.
	 *

	 * Context initialized listener is not allowed to throw exceptions and it seems there is no standard way to ask servlet
	 * container to abort launching the web application. Tiny container solution is to leave servlet context attribute
	 * {@link #ATTR_INSTANCE} null. On {@link AppServlet#init(javax.servlet.ServletConfig)} mentioned attribute is tested for
	 * null and, if so, permanently mark servlet unavailable.
	 *

	 * Implementation note: bootstrap process logic is based on assumption that this contextInitialized
	 * handler is called before servlets initialization. Here is the relevant excerpt from API-DOC: All
	 * ServletContextListeners are notified of context initialization before any filter or servlet in the web application is
	 * initialized.
	 *
	 * @param contextEvent context event provided by servlet container.
	 */
	@Override
	public void contextInitialized(ServletContextEvent contextEvent) {
		final ServletContext servletContext = contextEvent.getServletContext();

		/** Logger diagnostic context stores contextual information regarding current request. */
		LogContext logContext = LogFactory.getLogContext();
		logContext.put(LOG_CONTEXT_APP, servletContext.getContextPath().isEmpty() ? TinyContainer.ROOT_CONTEXT : servletContext.getContextPath().substring(1));

		final long start = System.currentTimeMillis();
		log.debug("Starting application |%s| container...", servletContext.getContextPath());

		Enumeration<String> parameterNames = servletContext.getInitParameterNames();
		while (parameterNames.hasMoreElements()) {
			final String name = parameterNames.nextElement();
			final String value = servletContext.getInitParameter(name);
			contextParameters.setProperty(name, value);
			log.debug("Load context parameter |%s| value |%s|.", name, value);
		}

		try {
			ConfigBuilder builder = new TinyConfigBuilder(servletContext, contextParameters);
			config(builder.build());

			Factory.bind(this);
			start();

			// set tiny container reference on servlet context attribute ONLY if no exception
			servletContext.setAttribute(TinyContainer.ATTR_INSTANCE, this);
			log.info("Application |%s| container started in %d msec.", appName, System.currentTimeMillis() - start);
		} catch (ConfigException e) {
			log.error(e);
			log.fatal("Bad container |%s| configuration.", appName);
		} catch (Throwable t) {
			log.dump(String.format("Fatal error on container |%s| start:", appName), t);
		}
	}

	/**
	 * Release resources used by this tiny container instance. After execution this method no HTTP requests can be handled.
	 *

	 * Implementation note: tiny container destruction logic is based on assumption that this
	 * contextDestroyed handler is called after all web application's servlets destruction. Here is the relevant
	 * excerpt from API-DOC: All servlets and filters have been destroy()ed before any ServletContextListeners are notified
	 * of context destruction.
	 *
	 * @param contextEvent context event provided by servlet container.
	 */
	@Override
	public void contextDestroyed(ServletContextEvent contextEvent) {
		log.debug("Context |%s| destroying.", appName);
		try {
			destroy();
		} catch (Throwable t) {
			log.dump(String.format("Fatal error on container |%s| destroy:", appName), t);
		}
	}

	/**
	 * Record session creation to logger trace.
	 *
	 * @param sessionEvent session event provided by servlet container.
	 */
	public void sessionCreated(HttpSessionEvent sessionEvent) {
		log.trace("Create HTTP session |%s|.", sessionEvent.getSession().getId());
	}

	/**
	 * Record session destroying for logger trace.
	 *
	 * @param sessionEvent session event provided by servlet container.
	 */
	public void sessionDestroyed(HttpSessionEvent sessionEvent) {
		log.trace("Destroy HTTP session |%s|.", sessionEvent.getSession().getId());
	}

	// --------------------------------------------------------------------------------------------
	// APPLICATION CONTEXT INTERFACE

	@Override
	public String getAppName() {
		return appName;
	}

	@Override
	public File getAppFile(String path) {
		return new File(privateDir, path);
	}

	@Override
	public String getProperty(String name) {
		return contextParameters.getProperty(name);
	}

	@Override
	public <T> T getProperty(String name, Class<T> type) {
		return ConverterRegistry.getConverter().asObject(contextParameters.getProperty(name), type);
	}

	@Override
	public Locale getRequestLocale() {
		return getInstance(RequestContext.class).getLocale();
	}

	@Override
	public String getRemoteAddr() {
		return getInstance(RequestContext.class).getRemoteHost();
	}

	// --------------------------------------------------------------------------------------------
	// SECURITY CONTEXT INTERFACE

	@Override
	public boolean login(String username, String password) {
		try {
			getHttpServletRequest().login(username, password);
		} catch (ServletException e) {
			// exception is thrown if request is already authenticated, servlet container authentication is not enabled or
			// credentials are not accepted
			// consider all these conditions as login fail but record the event to application logger
			log.debug(e);
			return false;
		}
		return true;
	}

	@Override
	public void login(Principal user) {
		final HttpServletRequest request = getHttpServletRequest();

		HttpSession session = request.getSession(true);
		if (user instanceof NonceUser) {
			final NonceUser nonce = (NonceUser) user;
			session.setMaxInactiveInterval(nonce.getMaxInactiveInterval());
		}

		try {
			session.setAttribute(ATTR_PRINCIPAL, user);
		} catch (IllegalStateException e) {
			// improbable condition: exception due to invalid session that was just created
			// it may occur only if another thread temper with login and somehow invalidates the session
			// while is arguable hard to believe it can theoretically happen an need to be handled
			// anyway, is not a security breach; if storing principal on session fails, session is not authenticated
			log.debug(e);
		}
	}

	@Override
	public void logout() {
		final HttpServletRequest request = getHttpServletRequest();

		try {
			request.logout();
		} catch (ServletException e) {
			// api-doc is not very explicit about this exception: ' If the logout fails'
			// swallow this exception but record to application logger
			log.debug(e);
		}

		HttpSession session = request.getSession(false);
		if (session != null) {
			// session invalidate takes care to 'unbind any objects bound to it'
			// but just to be on the safe side remove principal attribute explicitly

			try {
				session.removeAttribute(ATTR_PRINCIPAL);
				session.invalidate();
			} catch (IllegalStateException e) {
				// when enter 'if' block session is valid but could be changed from separated thread
				// swallow this exception but record to application logger
				log.debug(e);
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T extends Principal> T getUserPrincipal() {
		RequestContext context = getInstance(RequestContext.class);
		final HttpServletRequest request = context.getRequest();
		if (request == null) {
			log.debug("Attempt to retrieve user principal outside HTTP request.");
			return null;
		}

		// if authentication is provided by servlet container it should be a principal on HTTP request
		// otherwise it must be a session and on session it must be the principal object
		// if none from above just return null

		Principal principal = request.getUserPrincipal();
		if (principal != null) {
			return (T) principal;
		}

		HttpSession session = request.getSession();
		if (session == null) {
			return null;
		}

		try {
			return (T) session.getAttribute(ATTR_PRINCIPAL);
		} catch (IllegalStateException e) {
			// it can happen session to become invalid from another thread
			// this is a legal condition; do not even log it to debug
			return null;
		}
	}

	@Override
	public boolean isAuthenticated() {
		return getUserPrincipal() != null;
	}

	// --------------------------------------------------------------------------------------------
	// CONTAINER SPI

	@Override
	public String getLoginRealm() {
		return loginRealm;
	}

	@Override
	public String getLoginPage() {
		return loginPage;
	}

	@Override
	public void setProperty(String name, Object value) {
		if (!(value instanceof String)) {
			value = ConverterRegistry.getConverter().asString(value);
		}
		contextParameters.put(name, value);
	}

	// --------------------------------------------------------------------------------------------
	// UTILITY METHODS

	/**
	 * Get HTTP request from current request context.
	 *
	 * @return current HTTP request.
	 * @throws BugError if attempt to use not initialized HTTP request.
	 */
	private HttpServletRequest getHttpServletRequest() {
		RequestContext context = getInstance(RequestContext.class);
		HttpServletRequest request = context.getRequest();
		if (request == null) {
			throw new BugError("Attempt to use not initialized HTTP request.");
		}
		return request;
	}
}


package js.container;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import js.lang.InstanceInvocationHandler;
import js.lang.InvocationException;
import js.log.Log;
import js.log.LogFactory;
import js.transaction.Transaction;
import js.transaction.TransactionManager;
import js.util.Params;

/**
 * Invocation handler implementing container services for managed classes of {@link InstanceType#PROXY} type. Managed classes
 * declared as {@link InstanceType#PROXY} have the actual managed instance wrapped in a Java Proxy, dynamically generated. That
 * proxy routes all managed instance method invocations to this invocation handler {@link #invoke(Object, Method, Object[])}
 * method that, on its turn, delegates wrapped instance. Since all invocations pass through a single point is possible to add
 * cross-cutting functionality like transactions.
 *

 * Current version implements directly only logic related to transactional execution and delegates {@link ManagedMethod} for
 * method level service.
 *
 *
Transactions

 *

 * This class supports declarative transactions, both mutable and immutable. It uses {@link TransactionManager} to create a new
 * transaction, invoke managed instance method and commit transaction; on any exception performs rollback. This class uses
 * services provided by external implementation via {@link TransactionManager} interface and cannot work if there is no service
 * provider on run-time. Anyway, {@link TransactionalResource}, that is injected by constructor, does detect transactional
 * service provider and throws exception if not found.
 *
 *

 *                    +--------------------+  new  +-------------+  new  +---------+
 *                    | TransactionManager +-------> Transaction +-------> Session |
 *                    +---------+----------+       +-------------+       +---------+
 *                              |
 *                       +------v------+
 *                       | Transaction |
 *                       +-------------+
 *                       | session     |
 *                       +------v------+
 *                              |
 *               container      |                          TransactionalResource
 *               +--------------v---------------+  store    +----------------------+
 * invoke -------> tx = tm.createTransaction    +-----------> TLS<Session>         |
 *        <---+  |                              |           +------+------^--------+
 *            |  |    instance                  |                  |      |
 *            |  |    +-----------------------+ |  uses            |      |
 *            |  |    | database              <-+------------------+      |
 *            |  |    +-----------|-----------+ |                         |
 *            |  |    | method                | |                         |
 *            |  |    | database.getSession() | |                         |
 *            |  |    +-----------------------+ |                         |
 *            |  |    | ...                   | |                         |
 *            |  |    +-----------------------+ |                         |
 *            |  |                              |                         |
 *            |  | tx.commit / tx.rollback      |  release                |
 *            +--+ tx.close                     +-------------------------+
 *               +------------------------------+
 *               ContainerProxyHandler
 *

 *

 * Here is transaction handling algorithm implemented by managed proxy handler.
 *

 *
ManagedProxyHandler invokes createTransaction on TransactionResource
 *
TransactionalResource delegates transaction creation to TransactionManager
 *
TransactionManager creates transaction and session object
 *
TransactionManager returns transaction that contains session object
 *
ManagedProxyHandler stores session object on TransactionalResource
 *
ManagedProxyHandler uses transaction instance to control transaction life cycle
 *
ManagedProxyHandler invokes service method
 *
service method uses TransactionalResource to retrieve session object
 *
ManagedProxyHandler close transaction and release session from TransactionalResource
 *

 *
 * @author Iulian Rotaru
 * @version final
 */
final class ManagedProxyHandler implements InstanceInvocationHandler<Object> {
	/** Class logger. */
	private static Log log = LogFactory.getLog(ManagedProxyHandler.class);

	/** External resource that provides a transactional API. */
	private final TransactionalResource transactionalResource;

	/** Wrapped managed class. */
	private final ManagedClassSPI managedClass;

	/** Managed instance. */
	private final Object managedInstance;

	/**
	 * Construct non-transactional proxy invocation handler for given managed instance.
	 *
	 * @param managedClass managed class,
	 * @param managedInstance instance of managed class.
	 * @throws IllegalArgumentException if managedClass or managedInstance argument is null.
	 */
	public ManagedProxyHandler(ManagedClassSPI managedClass, Object managedInstance) {
		this(null, managedClass, managedInstance);
	}

	/**
	 * Construct transactional proxy invocation handler for given managed instance.
	 *
	 * @param transactionalResource transactional resource,
	 * @param managedClass managed class,
	 * @param managedInstance instance of managed class.
	 * @throws IllegalArgumentException if managedClass is null or not transactional or
	 *             managedInstance is null.
	 */
	public ManagedProxyHandler(TransactionalResource transactionalResource, ManagedClassSPI managedClass, Object managedInstance) {
		Params.notNull(managedClass, "Managed class");
		if (transactionalResource != null) {
			Params.isTrue(managedClass.isTransactional(), "Managed class is not transactional");
		}
		Params.notNull(managedInstance, "Managed instance");

		this.transactionalResource = transactionalResource;
		this.managedClass = managedClass;
		this.managedInstance = managedInstance;
	}

	/**
	 * Return wrapped implementation instance.
	 *
	 * @return wrapped implementation instance.
	 * @see #managedInstance
	 */
	@Override
	public Object getWrappedInstance() {
		return managedInstance;
	}

	/**
	 * Invocation handler implementation. Every method invocation on managed class interface is routed to this point. Here
	 * actual container services are implemented and method is invoked against wrapped instance.
	 *
	 * @param proxy instance of dynamically generated Java Proxy,
	 * @param method interface Java method about to invoke,
	 * @param args method invocation arguments.
	 * @return value returned by implementation method.
	 * @throws Throwable forward any exception rose by implementation method.
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		final ManagedMethodSPI managedMethod = managedClass.getManagedMethod(method);
		log.trace("Invoke |%s|.", managedMethod);

		if (!managedMethod.isTransactional()) {
			// execute managed method that is not included within transactional boundaries
			try {
				return managedMethod.invoke(managedInstance, args);
			} catch (Throwable t) {
				throw throwable(t, "Non transactional method |%s| invocation fails.", managedMethod);
			}
		}

		if (managedMethod.isImmutable()) {
			return executeImmutableTransaction(managedMethod, args);
		}
		return executeMutableTransaction(managedMethod, args);
	}

	/**
	 * Helper method for mutable transaction execution.
	 *
	 * @param managedMethod managed method to be executed into transactional scope,
	 * @param args managed method arguments.
	 * @return value returned by managed method.
	 * @throws Throwable forward any error rose by method execution.
	 */
	private Object executeMutableTransaction(ManagedMethodSPI managedMethod, Object[] args) throws Throwable {
		// store transaction session on current thread via transactional resource utility
		// it may happen to have multiple nested transaction on current thread
		// since all are created by the same transactional resource, all are part of the same session
		// and there is no harm if storeSession is invoked multiple times
		// also performance penalty is comparable with the effort to prevent this multiple write

		Transaction transaction = transactionalResource.createTransaction();
		transactionalResource.storeSession(transaction.getSession());

		try {
			Object result = managedMethod.invoke(managedInstance, args);
			transaction.commit();
			if (transaction.unused()) {
				log.debug("Method |%s| superfluously declared transactional.", managedMethod);
			}
			return result;
		} catch (Throwable throwable) {
			transaction.rollback();
			throw throwable(throwable, "Mutable transactional method |%s| invocation fail.", managedMethod);
		} finally {
			if (transaction.close()) {
				// it may happen to have multiple nested transaction on this thread
				// if this is the case, remove session from current thread only if outermost transaction is closed
				// of course if not nested transactions, remove at once
				transactionalResource.releaseSession();
			}
		}
	}

	/**
	 * Helper method for immutable transaction execution.
	 *
	 * @param managedMethod managed method to be executed into transactional scope,
	 * @param args managed method arguments.
	 * @return value returned by managed method.
	 * @throws Throwable forward any error rose by method execution.
	 */
	private Object executeImmutableTransaction(ManagedMethodSPI managedMethod, Object[] args) throws Throwable {
		Transaction transaction = transactionalResource.createReadOnlyTransaction();
		// see mutable transaction comment
		transactionalResource.storeSession(transaction.getSession());

		try {
			Object result = managedMethod.invoke(managedInstance, args);
			if (transaction.unused()) {
				log.debug("Method |%s| superfluously declared transactional.", managedMethod);
			}
			return result;
		} catch (Throwable throwable) {
			throw throwable(throwable, "Immutable transactional method |%s| invocation fail.", managedMethod);
		} finally {
			if (transaction.close()) {
				// see mutable transaction comment
				transactionalResource.releaseSession();
			}
		}
	}

	/**
	 * Prepare given throwable and dump it to logger with formatted message. Return prepared throwable. If throwable is
	 * {@link InvocationTargetException} or its unchecked related version, {@link InvocationException} replace it with root
	 * cause.
	 *
	 * @param throwable throwable instance,
	 * @param message formatted error message,
	 * @param args optional formatted message arguments.
	 * @return prepared throwable.
	 */
	private static Throwable throwable(Throwable throwable, String message, Object... args) {
		Throwable t = throwable;
		if (t instanceof InvocationException && t.getCause() != null) {
			t = t.getCause();
		}
		if (t instanceof InvocationTargetException && ((InvocationTargetException)t).getTargetException() != null) {
			t = ((InvocationTargetException) t).getTargetException();
		}
		message = String.format(message, args);
		log.dump(message, t);
		return t;
	}
}


/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
*/

package de.cologneintelligence.fitgoodies.file;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * This class takes a filter pattern and a File and returns
 * matching files.
 */
public class FileSelector {
	private final SimpleRegexFilter filter;
	private final File directory;

	/**
	 * Initializes a new selector.
	 *
	 * @param directory directory to use
	 * @param pattern   filename filter pattern
	 */
	public FileSelector(final File directory,
	                    final String pattern) {
		filter = new SimpleRegexFilter(pattern);
		this.directory = directory;
	}

	/**
	 * Returns the only file that matches the pattern. If no file matches, a
	 * null. If more than one file matches, a
	 * {@link FilenameNotUniqueException} is thrown.
	 *
	 * @return the matching file or null if no file matched
	 * @throws FilenameNotUniqueException more than one file matched the pattern
	 * @throws FileNotFoundException      thrown, if the directory does not exist.
	 */
	public File getUniqueFile()
			throws FilenameNotUniqueException, FileNotFoundException {
		File[] files = directory.listFiles(filter);

		if (files == null || files.length == 0) {
			throw new FileNotFoundException();
		}

		if (files.length > 1) {
			throw new FilenameNotUniqueException(filter.getPattern());
		}
		return files[0];
	}

	/**
	 * Returns the first matching file.
	 *
	 * @return the matching file or null if no file matches
	 * @throws FileNotFoundException thrown, if the directory does not exist
	 */
	public File getFirstFile() throws FileNotFoundException {
		File[] files = directory.listFiles(filter);

		if (files == null || files.length == 0) {
			throw new FileNotFoundException();
		}

		return files[0];
	}

	/**
	 * Returns a list of all matching files.
	 *
	 * @return all files which match the pattern
	 */
	public File[] getFiles() {
		final File[] files = directory.listFiles(filter);
		if (files == null) {
			return new File[0];
		} else {
			return files;
		}
	}

	/**
	 * Returns the last matching file.
	 *
	 * @return the matching file or null if no file matches
	 * @throws FileNotFoundException thrown, if the directory does not exist
	 */
	public File getLastFile() throws FileNotFoundException {
		File[] files = directory.listFiles(filter);
		if (files == null || files.length == 0) {
			throw new FileNotFoundException();
		}

		return files[files.length - 1];
	}
}


/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.cologneintelligence.fitgoodies.log4j;

import de.cologneintelligence.fitgoodies.Fixture;
import de.cologneintelligence.fitgoodies.htmlparser.FitCell;
import de.cologneintelligence.fitgoodies.util.FitUtils;
import org.apache.log4j.Appender;
import org.apache.log4j.spi.AppenderAttachable;

import java.util.List;
import java.util.Map;

/**
 * Fixture to analyze captured log data. Log messages can be analyzed by searing
 * strings in their messages and exception information.

 * The fixture contains 4 rows: the name of the logger, the name of the appender,
 * a command which can have parameters, and a expression to search. The parameter
 * column supports Cross References.
 * Only captured loggers can be analyzed. To capture loggers, see {@link SetupFixture}.
 *

 * The root logger is named "rootLogger".
 * Valid parameters are "Thread" and "MinLevel".
 *

 * Example:
 *

fitgoodies.log4j.LogFixture

 *
rootLogger	R	contains	successfully initialized

 *
rootLogger	R	notContains	critical error

 *

 * org.example.MyClass
 * stdout
 * containsException
 * IllegalArgumentException
 *

 *

 * org.example.MyClass
 * stdout
 * notContainsException
 * not found
 *

 *

 * org.example.MyClass
 * stdout
 * contains[Thread = main, MinLevel = Error]
 * timeout
 *

 *

 */
public class LogFixture extends Fixture {
	private final LoggerProvider loggerProvider;
	private final LogEventAnalyzerFactory logEventAnalyzerFactory;

	private static final int LOGGER_COLUMN = 0;
	private static final int APPENDER_COLUMN = 1;
	private static final int COMMAND_COLUMN = 2;
	private static final int CHECK_EXPRESSION_COLUMN = 3;

	private CaptureAppender appender;
    private List<FitCell> cells;

    /**
	 * Initializes a new {@code LogFixture} using a {@link LoggerProvider}
	 * and a {@link LogEventAnalyzerFactory}.
	 *
	 * @see #LogFixture(LoggerProvider, LogEventAnalyzerFactory)
	 * LogFixture(LoggerProvider, CellArgumentParserFactory, LogEventAnalyzerFactory)
	 */
	public LogFixture() {
		this(new LoggerProvider(), new LogEventAnalyzerFactory());
	}

	/**
	 * Initializes a new LogFixture.
	 *
	 * @param logs                    {@code LoggerProvider} to receive loggers.
	 * @param logEventAnalyzerFactory {@code LogEventAnalyzerFactory}
	 *                                to analyze log entries
	 */
	public LogFixture(final LoggerProvider logs,
	                  final LogEventAnalyzerFactory logEventAnalyzerFactory) {
		this.loggerProvider = logs;
		this.logEventAnalyzerFactory = logEventAnalyzerFactory;
	}

	/**
	 * Processes the table row {@code cells}.
	 *
	 * @param cells row to parse and process
	 */
	@Override
	protected void doCells(List<FitCell> cells) {
		this.cells = cells;
		this.appender = getAppender();

		if (appender != null) {
			try {
				executeCommand();
			} catch (final IllegalArgumentException e) {
				cells.get(COMMAND_COLUMN).exception("Illegal Format");
			}
		}
	}

	private void executeCommand() {
		Map<String, String> parameters =
				FitUtils.extractCellParameterMap(cells.get(COMMAND_COLUMN));
		String command = cells.get(COMMAND_COLUMN).getFitValue();
		getExpressionCellContent();

		dispatchCommand(command, parameters);
	}

	private String getExpressionCellContent() {
        FitCell cell = cells.get(CHECK_EXPRESSION_COLUMN);
		return validator.preProcess(cell);
	}

	private CaptureAppender getAppender() {
		String loggerName = cells.get(LOGGER_COLUMN).getFitValue();
		AppenderAttachable logger = getLogger(loggerName);

		if (logger == null) {
			cells.get(LOGGER_COLUMN).exception("Invalid logger");
			return null;
		}

		String appenderName = cells.get(APPENDER_COLUMN).getFitValue();
		String captureAppenderName = CaptureAppender.getAppenderNameFor(appenderName);

		final Appender appender = logger.getAppender(captureAppenderName);
		if (appender == null) {
			cells.get(APPENDER_COLUMN).exception("Invalid appender or appender not captured");
			return null;
		}
		return (CaptureAppender) appender;
	}

	private AppenderAttachable getLogger(String loggerName) {
		if ("rootLogger".equalsIgnoreCase(loggerName)) {
			return loggerProvider.getRootLogger();
		} else {
			return loggerProvider.getLogger(loggerName);
		}
	}

	private void dispatchCommand(String command, Map<String, String> parameters) {
        FitCell cell = cells.get(CHECK_EXPRESSION_COLUMN);
        LogEventAnalyzer analyzer = logEventAnalyzerFactory.getLogEventAnalyzerFor(
                validator, cell, appender.getAllEvents());

		if ("contains".equalsIgnoreCase(command)) {
			analyzer.processContains(parameters);
		} else if ("notContains".equalsIgnoreCase(command)) {
			analyzer.processNotContains(parameters);
		} else if ("containsException".equalsIgnoreCase(command)) {
			analyzer.processContainsException(parameters);
		} else if ("notContainsException".equalsIgnoreCase(command)) {
			analyzer.processNotContainsException(parameters);
		} else {
			cells.get(COMMAND_COLUMN).exception("unknown command");
		}
	}
}


package js.container;

import java.util.HashMap;
import java.util.Map;

import js.lang.BugError;

/**
 * Scope factory that creates thread local instances. An instance with {@link InstanceScope#THREAD}, once created, has the same
 * value for entire thread life span. If attempt to retrieve it again, from the same thread, its value is reused.
 *

 * Thread scope factory has an {@link #instancesPool} and attempt to retrieve managed instance from it, see
 * {@link #getInstance(InstanceKey)}; uses {@link #persistInstance(InstanceKey, Object)} to update instances pool. Both uses
 * provided instance key argument to store and retrieve instances.
 *

 * Instances pool uses thread local storage to keep instances but is not inheritable, that is, thread local instance is not
 * visible on child threads.
 *
 * @author Iulian Rotaru
 * @version final
 */
final class ThreadScopeFactory implements ScopeFactory {
	/**
	 * Managed instances pool for managed classes with thread scope. A managed class has a thread local storage created on the
	 * fly. Once instance saved into thread local, it is reused for entire thread life span. Implementation should be aware not
	 * to use {@link InheritableThreadLocal}.
	 */
	private Map<InstanceKey, ThreadLocal<Object>> instancesPool = new HashMap<>();

	@Override
	public InstanceScope getInstanceScope() {
		return InstanceScope.THREAD;
	}

	/**
	 * Retrieve instance from current thread, bound to given managed class or null if none found. Uses provided managed instance
	 * key to get instance from {@link #instancesPool}. Instance key argument should be not null.
	 *
	 * @param instanceKey managed instance key.
	 * @return current thread managed instance or null.
	 */
	@Override
	public Object getInstance(InstanceKey instanceKey) {
		// at this point managed class is guaranteed to be non null

		ThreadLocal<Object> tls = instancesPool.get(instanceKey);
		if (tls == null) {
			synchronized (instancesPool) {
				tls = instancesPool.get(instanceKey);
				if (tls == null) {
					tls = new ThreadLocal<>();
					instancesPool.put(instanceKey, tls);
				}
			}
			return null;
		}

		return tls.get();
	}

	/**
	 * Persist instance on current thread bound to given managed class. This method simply uses provided instance key argument
	 * to add instance to {@link #instancesPool}. Both arguments should to be not null.
	 *
	 * @param instanceKey managed instance key,
	 * @param instance managed instance.
	 */
	@Override
	public void persistInstance(InstanceKey instanceKey, Object instance) {
		// at this point managed class and instance are guaranteed to be non null

		ThreadLocal<Object> tls = instancesPool.get(instanceKey);
		if (tls == null) {
			throw new BugError("Invalid methods invocation sequence. Ensure getInstance() is invoked before and is executed in the same thread.");
		}
		tls.set(instance);
	}

	/** Clear all threads local storage and {@link #instancesPool}. */
	@Override
	public void clear() {
		for (ThreadLocal<Object> threadLocal : instancesPool.values()) {
			threadLocal.remove();
		}
		instancesPool.clear();
	}
}


package js.net;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletResponse;

import js.http.HttpHeader;
import js.log.Log;
import js.log.LogFactory;
import js.servlet.AppServlet;
import js.servlet.RequestContext;

/**
 * Servlet that handle HTTP requests for W3C Server-Sent Events. It is designed to work closely with {@link EventStream} and
 * basically creates associated event stream instance and run its {@link EventStream#loop()}.
 *

 * Servlet instance is running in a separated request thread and execute events stream loop as far client remains connected,
 * that is, there is an thread running this Servlet instance for every opened events stream. Of course there is a limit on the
 * number of concurrent events streams due to limited execution threads and sockets usable by a process.
 *
 * @author Iulian Rotaru
 * @version final
 */
public class EventStreamServlet extends AppServlet {
	/** Java serialization version. */
	private static final long serialVersionUID = 1856456540830763376L;

	/** Class logger. */
	private static final Log log = LogFactory.getLog(EventStreamServlet.class);

	/** Event stream manager. */
	private EventStreamManagerSPI eventStreamManager;

	/** Default constructor. */
	public EventStreamServlet() {
		log.trace("EventStreamServlet()");
	}

	/**
	 * Beside initialization inherited from {@link AppServlet#init(ServletConfig)} this method takes care to initialize event
	 * stream manager reference.
	 *
	 * @param config servlet configuration object.
	 * @throws UnavailableException if servlet initialization fails.
	 */
	@Override
	public void init(ServletConfig config) throws UnavailableException {
		super.init(config);
		log.trace("init(ServletConfig)");
		eventStreamManager = container.getInstance(EventStreamManager.class);
	}

	/**
	 * Create {@link EventStream} for session ID from request URI and run {@link EventStream#loop()} as far it returns true.
	 * This method takes also care to handle connections errors due to network or client failure. At event stream loop exit,
	 * graceful or due to error, unbind event stream from manager.
	 *

	 * If event stream cannot be created due to bad session ID responds with bad request, error code 400.
	 *

	 * Note that this method does not return as long client requesting for event stream is connected, keeping HTTP request
	 * thread and servlet allocated, even there is no event to send for this particular client.
	 *
	 * @param context HTTP request context.
	 * @throws IOException if HTTP response output stream fail to open.
	 */
	@Override
	protected void handleRequest(RequestContext context) throws IOException {
		log.trace("handleRequest(RequestContext)");
		final HttpServletResponse httpResponse = context.getResponse();
		final String sessionID = getEventStreamSessionID(context.getRequestPath());

		EventStream eventStream = eventStreamManager.createEventStream(sessionID);
		if (eventStream == null) {
			// a bad or heavy loaded client may send this request after session expiration or attempt to reuse old session ID
			sendBadRequest(context);
			return;
		}

		// 1. headers and content type should be initialized before response commit
		// 2. it seems that ServletResponse#getWriter() updates character set
		// excerpt from apidoc:
		// If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method
		// just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

		// so need to be sure headers are updated before writer opened

		httpResponse.setContentType("text/event-stream;charset=UTF-8");
		// no need to explicitly set character encoding since is already set by content type
		// httpResponse.setCharacterEncoding("UTF-8");

		httpResponse.setHeader(HttpHeader.CACHE_CONTROL, HttpHeader.NO_CACHE);
		httpResponse.addHeader(HttpHeader.CACHE_CONTROL, HttpHeader.NO_STORE);
		httpResponse.setHeader(HttpHeader.PRAGMA, HttpHeader.NO_CACHE);
		httpResponse.setDateHeader(HttpHeader.EXPIRES, 0);

		httpResponse.setHeader(HttpHeader.CONNECTION, HttpHeader.KEEP_ALIVE);

		eventStream.setRemoteHost(context.getRemoteHost());
		eventStream.setWriter(httpResponse.getWriter());
		try {
			eventStream.onOpen();
			log.debug("Event stream |%s| opened.", eventStream);
			while (eventStream.loop()) {
			}
		} finally {
			eventStream.onClose();
			eventStreamManager.destroyEventStream(eventStream);
			log.debug("Event stream |%s| closed.", sessionID);
		}
	}

	// --------------------------------------------------------------------------------------------
	// UTILITY METHODS

	/**
	 * Extract event stream session ID from request path. This method extracts last path component from request path with
	 * extension removed, if present. It is a sort of basename from file path. All next request paths with return
	 * the same session ID, 1234:
	 *

	 *
/1234.event,
	 *
/event/1234,
	 *
/1234,
	 *
/admin/1234.event
	 *
/admin/event/1234
	 *

	 * This allows for flexible event stream servlet mapping on deployment descriptor. Both mapping by path and extension can be
	 * used. Also extension can be anything. Anyway, this flexibility comes with a constraint: session ID cannot contain slash
	 * (/) or dot (.).
	 *

	 * Session ID is generated by event stream manager when client subscribes, see
	 * {@link EventStreamManager#subscribe(EventStreamConfig)}, then client sends session ID back to this servlet, as a HTTP
	 * request.
	 *
	 * @param requestPath request path, not null and with leading path separator.
	 * @return event stream session ID, never null.
	 */
	private static String getEventStreamSessionID(String requestPath) {
		int extensionSeparator = requestPath.lastIndexOf('.');
		if (extensionSeparator == -1) {
			extensionSeparator = requestPath.length();
		}

		// request URI is guaranteed to start with path separator
		// anyway, if missing below pathSeparator will be -1 + 1 = 0, pointing to entire request URI
		int pathSeparator = requestPath.lastIndexOf('/', extensionSeparator) + 1;
		return requestPath.substring(pathSeparator, extensionSeparator);
	}
}


package net.typedrest.vaadin.views;

import com.google.common.eventbus.EventBus;
import net.typedrest.*;
import net.typedrest.vaadin.forms.EntityForm;
import com.vaadin.data.Validator;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.ValoTheme;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.http.*;
import org.vaadin.dialogs.ConfirmDialog;

/**
 * Base class for building view components that create or update elements.
 *
 * @param <TEntity> The type of entity the component represents.
 * @param <TEndpoint> The type of {@link Endpoint} to operate on.
 */
public abstract class AbstractElementView<TEntity, TEndpoint extends Endpoint>
        extends AbstractEndpointView<TEndpoint> {

    protected final EntityForm<TEntity> entityForm;

    protected final Button saveButton = new Button("Save", x -> save()) {
        {
            addStyleName(ValoTheme.BUTTON_FRIENDLY);
        }
    };
    protected final HorizontalLayout buttonsLayout = new HorizontalLayout(saveButton) {
        {
            setSpacing(true);
        }
    };

    protected final VerticalLayout masterLayout;

    /**
     * Creates a new REST element component.
     *
     * @param endpoint The REST endpoint this component operates on.
     * @param eventBus Used to send event between components.
     * @param entityForm A component for viewing/modifying entity instances.
     */
    protected AbstractElementView(TEndpoint endpoint, EventBus eventBus, EntityForm<TEntity> entityForm) {
        super(endpoint, eventBus);

        this.entityForm = entityForm;

        masterLayout = new VerticalLayout(entityForm, buttonsLayout);
        masterLayout.setComponentAlignment(buttonsLayout, Alignment.MIDDLE_RIGHT);
        masterLayout.setMargin(true);
        masterLayout.setSpacing(true);
        setCompositionRoot(masterLayout);

        setHeight(masterLayout.getHeight() * 1.2f, masterLayout.getHeightUnits());
    }

    /**
     * Saves the input and closes the {@link Window} (if present).
     */
    public void save() {
        try {
            onSave();
            close();
        } catch (IOException | IllegalArgumentException | IllegalAccessException | Validator.InvalidValueException ex) {
            onError(ex);
        } catch (IllegalStateException ex) {
            // This usually inidicates a "lost update"
            ConfirmDialog.show(getUI(), ex.getLocalizedMessage() + "\nDo you want to refresh this page loosing any changes you have made?", (ConfirmDialog cd) -> {
                if (cd.isConfirmed()) {
                    refresh();
                }
            });
        }
    }

    /**
     * Handler for saving the input.
     *
     * @throws IOException Network communication failed.
     * @throws IllegalArgumentException {@link HttpStatus#SC_BAD_REQUEST}
     * @throws IllegalAccessException {@link HttpStatus#SC_UNAUTHORIZED} or
     * {@link HttpStatus#SC_FORBIDDEN}
     * @throws FileNotFoundException {@link HttpStatus#SC_NOT_FOUND} or
     * {@link HttpStatus#SC_GONE}
     * @throws IllegalStateException The entity has changed since it was last
     * retrieved with {@link #onLoad()}. Your changes were rejected to prevent a
     * lost update.
     * @throws Validator.InvalidValueException The user input is invalid.
     * @throws RuntimeException Other non-success status code.
     */
    protected abstract void onSave()
            throws IOException, IllegalArgumentException, IllegalAccessException, FileNotFoundException, IllegalStateException, Validator.InvalidValueException;
}


/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
*/

package de.cologneintelligence.fitgoodies.database;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

/**
 * Helper class to manage database connection information.
 * To set the values with HTML, you can use a {@link SetupFixture}.
 */
public class SetupHelper {
	private String user;
	private String password;
	private String connectionString;

	/**
	 * Sets the database driver. {@code driverName} must be a fully
	 * qualified class name and the class must be in java's class path.
	 * Unless the driver is already registered, {@code setProvider}
	 * registers it at the {@code java.sql.DriverManager}.
	 *
	 * @param driverName fully qualified class name of a {@code java.sql.Driver}.
	 * @throws Exception thrown if the class could not be found, casted or
	 *                   registered.
	 */
	public static void setProvider(final String driverName) throws Exception {
		Driver driver = (Driver) Class.forName(driverName).newInstance();
		Enumeration<Driver> drivers = DriverManager.getDrivers();
		while (drivers.hasMoreElements()) {
			if (drivers.nextElement().getClass().equals(driver.getClass())) {
				return;
			}
		}

		DriverManager.registerDriver(driver);
	}

	/**
	 * Sets the username to {@code userName}.
	 *
	 * @param userName username to set
	 * @see #getUser() getUser()
	 */
	public void setUser(final String userName) {
		this.user = userName;
	}

	/**
	 * Returns the selected username.
	 *
	 * @return the username
	 * @see #setUser(String) setUser(String)
	 */
	public String getUser() {
		return user;
	}

	/**
	 * Returns the selected password.
	 *
	 * @return the password
	 * @see #setPassword(String) setPassword(String)
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * Sets the password to {@code pw}.
	 *
	 * @param pw the password to set
	 * @see #getPassword() getPassword()
	 */
	public void setPassword(final String pw) {
		this.password = pw;
	}

	/**
	 * Returns the selected connection string.
	 * The connection string format depends on the selected provider.
	 *
	 * @return the selected connection string
	 * @see #setConnectionString(String) setConnectionString(String)
	 */
	public String getConnectionString() {
		return connectionString;
	}

	/**
	 * Set the connection string to {@code connectString}.
	 * The connection string format depends on the selected provider.
	 *
	 * @param connectString the connection string to use
	 * @see #getConnectionString() getConnectionString()
	 */
	public void setConnectionString(final String connectString) {
		this.connectionString = connectString;
	}

	/**
	 * Returns a {@code java.sql.Connection} using the saved connection
	 * string, authenticating with the saved username and password.
	 *
	 * @return an instance of java.sql.Connection
	 * @throws SQLException thrown by the {@code DriverManager} indicating
	 *                      some kind of problem.
	 */
	public Connection getConnection() throws SQLException {
		return DriverManager.getConnection(connectionString, user, password);
	}
}


/**
 * Copyright (C) 2015 Michael Schnell. All rights reserved.
 * http://www.fuin.org/
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library. If not, see http://www.gnu.org/licenses/.
 */
package org.fuin.srcgen4j.core.base;

import org.fuin.objects4j.common.Contract;
import org.fuin.srcgen4j.commons.Config;
import org.fuin.srcgen4j.commons.ParserConfig;

/**
 * Base class for all parsers.
 *
 * @param <CONFIG_TYPE>
 *            Type of the concrete configuration.
 */
public abstract class AbstractParser<CONFIG_TYPE> {

    private Class<CONFIG_TYPE> concreteConfigClass;

    /**
     * Constructor with class.
     *
     * @param concreteConfigClass
     *            Type of the configuration.
     */
    public AbstractParser(final Class<CONFIG_TYPE> concreteConfigClass) {
        super();
        Contract.requireArgNotNull("concreteConfigClass", concreteConfigClass);
        this.concreteConfigClass = concreteConfigClass;
    }

    /**
     * Returns the parser configuration.
     *
     * @param config
     *            Wrapping parser configuration that contains the concrete one.
     *
     * @return Parser specific configuration.
     */
    @SuppressWarnings("unchecked")
    protected final CONFIG_TYPE getConcreteConfig(final ParserConfig config) {
        final Config<ParserConfig> cfg = config.getConfig();
        if (cfg == null) {
            throw new IllegalStateException(
                    "The configuration is expected to be of type '" + concreteConfigClass.getName() + "', but was: null");
        } else {
            if (!(concreteConfigClass.isAssignableFrom(cfg.getConfig().getClass()))) {
                throw new IllegalStateException(
                        "The configuration is expected to be of type '" + concreteConfigClass.getName() + "', but was: "
                                + cfg.getConfig().getClass().getName() + " - Did you add the configuration class to the JXB context?");
            }
        }
        return (CONFIG_TYPE) cfg.getConfig();
    }
}


package js.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;

import js.container.ContainerSPI;
import js.log.Log;
import js.log.LogFactory;
import js.util.Strings;

/**
 * Servlet filter for request pre-processing. This filter is a critical part of the request routing process and complements
 * servlet container implementation. A request for Tiny Container has mandatory context path, optional locale and security
 * domain, followed by servlet path and path information. This filter is executed before servlet container mapping and takes
 * care to remove locale and security domain. This way servlet mapping from deployment descriptor can focus only on servlet
 * path.
 *

 * Locale is used only if application is built for multiple locales; locale is a two letter language code, ISO 3166-1. Security
 * domain is present if application uses roles based security provided by servlet container. This filter extracts locale and
 * security domain from current request URI and forward it.
 *
 *

 * request-uri = "/" context-path ["/" locale] ["/" security-domain] "/" servlet-path ["/" path-info]
 *

 *
 * Note that servlet container security is enacted before this filter execution and deployment descriptor should consider locale
 * when mapping web-resource-collection from security-constrain. See routing details on Request Routing from Tiny Container Overview.
 *

 * Current request pre-processor version has two filter parameters: locale and security-domain. Both
 * are comma separated lists. As stated locale item should be two letter language code and
 * security-domain item should be path names used by declarative security constrain.
 *
 *

 * <filter>
 * 	<filter-name>request-preprocessor</filter-name>
 * 	<filter-class>js.servlet.RequestPreprocessor</filter-class>
 * 	<init-param>
 * 		<param-name>locale</param-name>
 * 		<param-value>en,iw,ro</param-value>
 * 	</init-param>
 * 	<init-param>
 * 		<param-name>security-domain</param-name>
 * 		<param-value>admin,info</param-value>
 * 	</init-param>
 * </filter>
 * <filter-mapping>
 * 	<filter-name>request-preprocessor</filter-name>
 * 	<url-pattern>/*</url-pattern>
 * </filter-mapping>
 *

 *
 * It is considered a resource not found and rejected with 404 if a request URI contains a locale code that is not listed into
 * filter parameter. If locale filter parameter is not declared all locale codes that may be present into request
 * URI are passed unprocessed. If request URI contains a security domain that is not listed into security-domain
 * filter parameter, it is forwarded unprocessed. If request URI is for a static resource this filter forward request URI as it
 * is.
 *
 * @author Iulian Rotaru
 * @version final
 */
public class RequestPreprocessor implements Filter {
	/** Class logger. */
	private static final Log log = LogFactory.getLog(RequestPreprocessor.class);

	/**
	 * The name of locale filter parameter. Locale filter parameter contains a comma separated list of two letters
	 * language code, ISO 3166-1. It is loaded on {@link #locales} field. If application does not have multiple locales support
	 * this filter parameter is not defined.
	 */
	private static final String PARAM_LOCALE = "locale";

	/**
	 * The name of security-domain filter parameter. Security domain filter parameter contains a comma separated
	 * list of paths, as declared on url-pattern from security-constrain. If application does not use
	 * role base security provided by servlet container this filter parameter is not declared. This filter parameter is loaded
	 * into {@link #securityDomains} field.
	 */
	private static final String PARAM_SECURITY_DOMAIN = "security-domain";

	/** Application tiny container, service provider interface. */
	private ContainerSPI container;

	/** Locale list loaded from locale filter parameter, default to empty list if filter parameter is not declared. */
	private List<String> locales = Collections.emptyList();

	/**
	 * Security domains list loaded from security-domain filter parameter, default to empty list if filter
	 * parameter is not declared.
	 */
	private List<String> securityDomains = Collections.emptyList();

	/**
	 * Load locale codes and security domains lists from filter parameters. Filter parameter is a list of command separated
	 * items. If related filter parameter is not declared, field is initialized to empty list.
	 *

	 * This filter loads tiny container reference from servlet context attribute {@link TinyContainer#ATTR_INSTANCE}. If there
	 * is no servlet context attribute with the that name this initialization fails with filter permanently unavailable.
	 *
	 * @param config filter configuration object.
	 * @throws UnavailableException if tiny container is not properly initialized.
	 */
	@Override
	public void init(FilterConfig config) throws UnavailableException {
		log.trace("init(FilterConfig)");

		// is safe to store container reference on filter instance since container has application life span
		container = (ContainerSPI) config.getServletContext().getAttribute(TinyContainer.ATTR_INSTANCE);
		if (container == null) {
			log.fatal("Tiny container instance not properly created, probably misconfigured. Request preprocessor permanently unvailable.");
			throw new UnavailableException("Tiny container instance not properly created, probably misconfigured.");
		}

		String localeParameter = config.getInitParameter(PARAM_LOCALE);
		if (localeParameter != null) {
			locales = Strings.split(localeParameter, ',');
			for (String locale : locales) {
				log.debug("Register locale |%s| for request pre-processing.", locale);
			}
		}

		String securityDomainParameter = config.getInitParameter(PARAM_SECURITY_DOMAIN);
		if (securityDomainParameter != null) {
			securityDomains = Strings.split(securityDomainParameter, ',');
			for (String securityDomain : securityDomains) {
				log.debug("Register security domain |%s| for request pre-processing.", securityDomain);
			}
		}
	}

	/** Destroy operation is required by filter interface but in request pre-processor implementation is NOP. */
	@Override
	public void destroy() {
		log.trace("destroy()");
	}

	/**
	 * Search request URI for locale and security domain, by comparing with internal lists, and remove found values. Update
	 * locale, security domain and request path on context request from current thread, see
	 * {@link RequestContext#setLocale(Locale)}, {@link RequestContext#setSecurityDomain(String)} and
	 * {@link RequestContext#setRequestPath(String)}.
	 *

	 * Remove locale and security context from current request URI and forward it. If current request URI is for a static
	 * resource, that is, an existing file this filter does nothing.
	 *

	 * It is considered a resource not found and rejected with 404 if a request URI contains a locale code that is not listed
	 * into filter parameter. If locale filter parameter is not declared all locale code that may be present into
	 * request URI are passed unprocessed. If request URI contains a security domain that is not listed into
	 * security-domain filter parameter, it is forwarded unprocessed.
	 *
	 * @param request servlet request,
	 * @param response servlet response,
	 * @param chain filter chain.
	 * @throws IOException for failure on underlying request and response streams.
	 * @throws ServletException if filter chaining or request forwarding fails.
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		String requestURI = httpRequest.getRequestURI();
		String contextPath = httpRequest.getContextPath();
		String requestPath = requestURI.substring(contextPath.length());

		// request-uri = context-path request-path
		// context-path = "/" path-component
		// request-path = 1*("/" path-component)

		File file = new File(request.getServletContext().getRealPath(requestPath));
		if (file.exists()) {
			chain.doFilter(request, response);
			return;
		}

		// request-path = ["/" locale] ["/" security-domain] 1*("/" path-component)

		RequestContext context = container.getInstance(RequestContext.class);

		String queryString = httpRequest.getQueryString();
		context.setRequestURL(queryString != null ? Strings.concat(requestURI, '?', queryString) : requestURI);

		if (!locales.isEmpty()) {
			for (String locale : locales) {
				if (startsWith(requestPath, locale)) {
					requestPath = requestPath.substring(locale.length() + 1);
					context.setLocale(new Locale(locale));
					break;
				}
			}
		}

		for (String securityDomain : securityDomains) {
			if (startsWith(requestPath, securityDomain)) {
				requestPath = requestPath.substring(securityDomain.length() + 1);
				context.setSecurityDomain(securityDomain);
				break;
			}
		}

		context.setRequestPath(requestPath);
		request.getRequestDispatcher(requestPath).forward(request, response);
	}

	/**
	 * Test if request path starts with path component. This predicate returns true if first path component from given request
	 * path equals requested path component. Comparison is not case sensitive. Request path should start with path separator,
	 * otherwise this predicate returns false.
	 *
	 * @param requestPath request path to test,
	 * @param pathComponent path component that is compared with first path component from request path.
	 * @return true if request path starts with path component.
	 */
	private static boolean startsWith(String requestPath, String pathComponent) {
		if (requestPath.charAt(0) != '/') {
			return false;
		}
		int i = 1;
		for (int j = 0; i < requestPath.length(); ++i, ++j) {
			if (requestPath.charAt(i) == '/') {
				return j == pathComponent.length();
			}
			if (j == pathComponent.length()) {
				return false;
			}
			if (Character.toLowerCase(requestPath.charAt(i)) != Character.toLowerCase(pathComponent.charAt(j))) {
				return false;
			}
		}
		return false;
	}
}


/**
 * Copyright (C) 2015 Michael Schnell. All rights reserved.
 * http://www.fuin.org/
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library. If not, see http://www.gnu.org/licenses/.
 */
package org.fuin.srcgen4j.core.emf;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.fuin.srcgen4j.commons.ArtifactFactory;
import org.fuin.srcgen4j.commons.ArtifactFactoryConfig;
import org.fuin.srcgen4j.commons.Config;
import org.fuin.srcgen4j.commons.GeneratorConfig;
import org.fuin.srcgen4j.commons.InitializableElement;
import org.fuin.srcgen4j.commons.SrcGen4JContext;
import org.fuin.xmlcfg4j.AbstractElement;

/**
 * Configuration for a {@link EMFGenerator}.
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "emf-generator-config")
public class EMFGeneratorConfig extends AbstractElement implements InitializableElement<EMFGeneratorConfig, Config<GeneratorConfig>> {

    @Nullable
    @Valid
    @XmlElement(name = "artifact-factory")
    private List<ArtifactFactoryConfig> factoryConfigs;

    private transient List<ArtifactFactory<?>> factories;

    /**
     * Default constructor.
     */
    public EMFGeneratorConfig() {
        super();
    }

    @Override
    public final EMFGeneratorConfig init(final SrcGen4JContext context, final Config<GeneratorConfig> parent,
            final Map<String, String> vars) {

        inheritVariables(vars);
        if (factoryConfigs != null) {
            for (final ArtifactFactoryConfig factoryConfig : factoryConfigs) {
                factoryConfig.init(context, getVarMap());
            }
        }
        return this;
    }

    /**
     * Returns a list of factories for the given model type.
     *
     * @param modelType
     *            Model type to return artifact factories for.
     *
     * @return List of factories that accept the given model type.
     *
     * @param <MODEL>
     *            Type of the model to create an artifact for.
     */
    @SuppressWarnings("unchecked")
    @NotNull
    public final <MODEL> List<ArtifactFactory<MODEL>> getFactories(final Class<MODEL> modelType) {
        final List<ArtifactFactory<MODEL>> list = new ArrayList<ArtifactFactory<MODEL>>();
        if (factories == null) {
            factories = new ArrayList<ArtifactFactory<?>>();
            if (factoryConfigs != null) {
                for (final ArtifactFactoryConfig factoryConfig : factoryConfigs) {
                    factories.add(factoryConfig.getFactory());
                }
            }
        }
        for (final ArtifactFactory<?> factory : factories) {
            if (modelType.isAssignableFrom(factory.getModelType())) {
                list.add((ArtifactFactory<MODEL>) factory);
            }
        }
        return list;
    }

}


/*
 * Copyright (c) 2002 Cunningham & Cunningham, Inc.
 * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
 *
 * This file is part of FitGoodies.
 *
 * FitGoodies is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FitGoodies is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FitGoodies.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.cologneintelligence.fitgoodies.date;

import de.cologneintelligence.fitgoodies.typehandler.TypeHandler;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Helper class which holds information about date formats and
 * allows to parse date string.
 *

 * This class should be used whenever a {@link TypeHandler} parses a date.
 */
public final class FitDateHelper {
	private Locale locale;
    private TimeZone timezone;
	private String format;

	public FitDateHelper() {
		locale = Locale.getDefault();
		format = "MM/dd/yyyy";
        timezone = TimeZone.getDefault();
	}

	/**
	 * Sets the locale to be used.
	 *

	 * Accepts the formats:
	 *

	 *
en

	 *
en_US

	 *
en_US_WIN

	 *

	 *
	 * @param localeName name of the locale to use
	 * @throws IllegalArgumentException if the localeName could not be parsed
	 * @see #getLocale() getLocale
	 */
	public void setLocale(final String localeName) {
		locale = parseLocale(localeName);
	}

	public Locale parseLocale(String localeName) {
		String[] parts = localeName.split("_");
		Locale result;
		if (parts.length == 1) {
			result = new Locale(parts[0]);
		} else if (parts.length == 2) {
			result = new Locale(parts[0], parts[1]);
		} else if (parts.length == 3) {
			result = new Locale(parts[0], parts[1], parts[2]);
		} else {
			throw new IllegalArgumentException("Locale " + localeName + " not valid");
		}
		return result;
	}

	/**
	 * Returns the selected locale.
	 *
	 * @return the selected locale.
	 * @see #setLocale(String) setLocale(String)
	 */
	public Locale getLocale() {
		return locale;
	}

	/**
	 * Sets the format which is used to parse dates to {@code formatString}.
	 * The string must be valid as a {@link SimpleDateFormat} format string.
	 *
	 * @param formatString the format string
	 * @see #getFormat() getFormat()
	 */
	public void setFormat(final String formatString) {
		format = formatString;
	}

	/**
	 * Gets the selected format.
	 *
	 * @return the used format string
	 * @see #setFormat(String) setFormat(String)
	 */
	public String getFormat() {
		return format;
	}

    public void setTimezone(String timezone) {
        this.timezone = TimeZone.getTimeZone(timezone);
    }

    public TimeZone getTimezone() {
        return timezone;
    }

    /**
	 * Parses {@code string} and returns a valid Date object.
	 * For parsing, a {@link SimpleDateFormat} object is used.
	 *
	 * @param string the string which represents the date
	 * @return the date which is represented by {@code string}
	 * @throws ParseException thrown, if {@code string} can not be parsed.
	 */
	public Date getDate(final String string) throws ParseException {
		return getDateFormat(format, locale).parse(string);
	}

	private SimpleDateFormat getDateFormat(String dateFormat, Locale dateLocale) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, dateLocale);
        simpleDateFormat.setTimeZone(timezone);
        return simpleDateFormat;
	}

	/**
	 * Parses {@code string} and returns a valid Date object.
	 * For parsing, a {@link SimpleDateFormat} object is used.
	 *
	 * @param string       the string which represents the date
	 * @param formatString a valid SimpleDateFormat format string
	 * @param localeName   the name of the locale to use, for example en_US
	 * @return the date which is represented by {@code string}
	 * @throws ParseException thrown, if {@code string} can not be parsed.
	 */
	public Date getDate(final String string, final String formatString, final String localeName) throws ParseException {
		return getDateFormat(formatString, parseLocale(localeName)).parse(string);
	}

	public Date parse(String s, String parameter) throws ParseException {
		if (parameter == null) {
			return getDate(s);
		} else {
			final String[] parameters = parameter.split("\\s*,\\s*", 2);
			if (parameters.length < 2) {
				throw new ParseException("Parameter must have the format [localname, format]", 0);
			}
			return getDate(s, parameters[1], parameters[0]);
		}
	}

	public String toString(Date s) {
		return getDateFormat(format, locale).format(s);
	}
}


package net.typedrest.vaadin.views;

import com.google.common.eventbus.EventBus;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Window;

/**
 * Base class for building view components that use an {@link EventBus} and can
 * be wrapped in {@link Window}s.
 */
public abstract class ViewComponent
        extends CustomComponent implements View {

    /**
     * Used to send event between components.
     */
    protected final EventBus eventBus;

    /**
     * Creates a new view component.
     *
     * @param eventBus Used to send event between components.
     */
    protected ViewComponent(EventBus eventBus) {
        this.eventBus = eventBus;
    }

    private boolean eventBusRegistered;

    @Override
    public void attach() {
        super.attach();

        if (!eventBusRegistered) {
            eventBus.register(this);
            eventBusRegistered = true;
        }
    }

    @Override
    public void detach() {
        if (eventBusRegistered) {
            eventBus.unregister(this);
            eventBusRegistered = false;
        }

        super.detach();
    }

    /**
     * Opens a child component as a {@link Window}.
     *
     * @param component The child component to open.
     */
    protected void open(ViewComponent component) {
        getUI().addWindow(component.asWindow());
    }

    private Window containingWindow;

    /**
     * Wraps the control in a {@link Window}.
     *
     * @return The newly created window.
     */
    protected Window asWindow() {
        if (containingWindow == null) {
            containingWindow = new Window(getCaption(), this);
            containingWindow.setWidth(80, Unit.PERCENTAGE);
            containingWindow.setHeight(80, Unit.PERCENTAGE);
            containingWindow.center();
        }
        return containingWindow;
    }

    /**
     * Closes the containing {@link Window}.
     */
    protected void close() {
        if (containingWindow != null) {
            containingWindow.close();
        }
    }

    @Override
    public void setCaption(String caption) {
        super.setCaption(caption);
        if (containingWindow != null) {
            containingWindow.setCaption(caption);
        }
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
    }
}


package js.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import js.container.InstanceKey;
import js.container.InstanceScope;
import js.container.ScopeFactory;
import js.core.AppFactory;
import js.lang.BugError;

/**
 * Scope factory for managed classes with HTTP session scope. A managed instance with {@link InstanceScope#SESSION} scope is
 * stateful across a single HTTP session. Managed instance is stored on HTTP session attribute; when HTTP session expires,
 * attribute is removed and session managed instance becomes candidate for GC.
 *

 * Session scope factory uses HTTP session to retrieve previously stored managed instance via {@link #getInstance(InstanceKey)};
 * HTTP session is updated by {@link #persistInstance(InstanceKey, Object)}. Both uses provided key argument for instance
 * storage and retrieval.
 *
 * @author Iulian Rotaru
 * @version final
 */
final class SessionScopeFactory implements ScopeFactory {
	/** Reference to parent application factory. */
	private AppFactory appFactory;

	/**
	 * Construct session scope factory instance.
	 *
	 * @param factory parent application factory.
	 */
	public SessionScopeFactory(AppFactory factory) {
		this.appFactory = factory;
	}

	@Override
	public InstanceScope getInstanceScope() {
		return InstanceScope.SESSION;
	}

	/**
	 * Retrieve instance from current HTTP session, bound to given instance key or null if none found. Uses provided instance
	 * key argument as HTTP session attribute name. Managed instance key argument should be not null.
	 *

	 * Access to HTTP session is obtained from HTTP request; therefore, it is considered a bug if attempt to use this method
	 * outside a HTTP request thread.
	 *

	 * Implementation note: this method could have side effect. It creates the HTTP session if there is none on current
	 * HTTP request.
	 *
	 * @param instanceKey managed instance key,
	 * @return managed instance or null.
	 * @throws BugError if attempt to use this method outside a HTTP request.
	 */
	@Override
	public Object getInstance(InstanceKey instanceKey) {
		// at this point managed instance key is guaranteed to be non null

		// SESSION instances are stored on current HTTP session as named attribute value, using provided instance key
		// HTTP session is created on the fly if necessary
		// if HTTP session exists and possesses an attribute with instance key, simply returns stored instance
		// when HTTP session expires attribute values are removed and SESSION instances are garbage collected

		HttpSession httpSession = getSession(instanceKey);
		return httpSession.getAttribute(instanceKey.getValue());
	}

	/**
	 * Persist instance on current HTTP session, bound to given managed instance key. This method simply uses
	 * instanceKey to add instance as HTTP session attribute. Both arguments should to be not null.
	 *

	 * Access to HTTP session is obtained from HTTP request; therefore, it is considered a bug if attempt to use this method
	 * outside a HTTP request thread.
	 *

	 * Implementation note: this method could have side effect. It creates the HTTP session if there is none on current
	 * HTTP request.
	 *
	 * @param instanceKey managed instance key,
	 * @param instance managed instance.
	 * @throws BugError if attempt to use this method outside a HTTP request.
	 */
	@Override
	public void persistInstance(InstanceKey instanceKey, Object instance) {
		// at this point key and instance arguments are guaranteed to be non null

		HttpSession httpSession = getSession(instanceKey);
		httpSession.setAttribute(instanceKey.getValue(), instance);
	}

	/**
	 * Get HTTP session from current request, creating it if necessary. This method should be call inside a request context
	 * otherwise bug error is thrown.
	 *
	 * @param instanceKey managed instance key.
	 * @return current request HTTP session.
	 * @throws BugError if attempt to use this method outside a HTTP request.
	 */
	private HttpSession getSession(InstanceKey instanceKey) {
		RequestContext requestContext = appFactory.getInstance(RequestContext.class);
		HttpServletRequest httpRequest = requestContext.getRequest();
		if (httpRequest == null) {
			throw new BugError("Invalid web context due to null HTTP request. Cannot create managed instance for |%s| with scope SESSION.", instanceKey);
		}

		// create HTTP session if missing; accordingly API httpSession is never null if 'create' flag is true
		return httpRequest.getSession(true);
	}

	/** This method does nothing and leaves session instances release on servlet container. */
	@Override
	public void clear() {
	}
}