src/main/java/org/remitt/datastore/DbEligibilityJob.java
public class DbEligibilityJob {

	static final Logger log = Logger.getLogger(DbEligibilityJob.class);

	public static boolean addEligibilityJob(String username, String plugin,
			Map<EligibilityParameter, String> payload) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("INSERT INTO tEligibilityJobs "
					+ " ( user, stamp, plugin, payload, completed ) "
					+ " VALUES ( ?, NOW(), ?, ?, FALSE ) " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, plugin);
			cStmt.setObject(3, payload);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

	public static boolean resubmitEligibilityJob(String username, Integer id) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		// Need to make sure that we're taking the failed job off the stack.
		{
			PreparedStatement cStmt = null;
			try {
				cStmt = c.prepareStatement("UPDATE tEligibilityJobs "
						+ " SET processed = NOW(), completed = TRUE "
						+ " WHERE user = ? AND id = ? ; ");
				cStmt.setString(1, username);
				cStmt.setInt(2, id);
				cStmt.execute();
				success = true;
			} catch (NullPointerException npe) {
				log.error("Caught NullPointerException", npe);
			} catch (Throwable e) {
				log.error("Caught Throwable", e);
			} finally {
				DbUtil.closeSafely(cStmt);
			}
		}

		{
			PreparedStatement cStmt = null;
			try {
				cStmt = c
						.prepareStatement("INSERT INTO tEligibilityJobs "
								+ " ( user, stamp, plugin, payload, completed, resubmission ) "
								+ " SELECT user, stamp, plugin, payload, FALSE, TRUE "
								+ " FROM tEligibilityJobs WHERE id = ? AND user = ? "
								+ ";");
				cStmt.setInt(1, id);
				cStmt.setString(2, username);
				cStmt.execute();
				success = true;
			} catch (NullPointerException npe) {
				log.error("Caught NullPointerException", npe);
			} catch (Throwable e) {
				log.error("Caught Throwable", e);
			} finally {
				DbUtil.closeSafely(cStmt);
				DbUtil.closeSafely(c);
			}
		}
		return success;
	}

	public static List<Integer> getUnprocessedEligibilityJobList() {
		Connection c = Configuration.getConnection();

		List<Integer> output = new ArrayList<Integer>();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT id " + " FROM tEligibilityJobs "
					+ " WHERE completed = FALSE;");

			boolean hadResults = cStmt.execute();
			if (hadResults) {
				ResultSet r = cStmt.getResultSet();
				while (r.next()) {
					output.add(r.getInt("id"));
				}
				r.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return output;
	}

	@SuppressWarnings("unchecked")
	public static EligibilityJob getEligibilityJobById(Integer id) {
		Connection c = Configuration.getConnection();

		EligibilityJob output = new EligibilityJob();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT * " + " FROM tEligibilityJobs "
					+ " WHERE id = ?;");
			cStmt.setInt(1, id);

			boolean hadResults = cStmt.execute();
			if (hadResults) {
				ResultSet r = cStmt.getResultSet();
				r.next();
				output.setId(r.getInt("id"));
				output.setUsername(r.getString("username"));
				output.setPlugin(r.getString("plugin"));
				output.setPayload((HashMap<EligibilityParameter, String>) r
						.getObject("payload"));
				output.setResponse((EligibilityResponse) r
						.getObject("response"));
				output.setResubmission(r.getBoolean("resubmission"));
				r.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
			output = null;
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
			output = null;
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return output;
	}

	public static boolean saveEligibilityJob(String username, Integer id,
			EligibilityResponse response) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("UPDATE tEligibilityJobs "
					+ " SET response = ?, processed = NOW(), completed = TRUE "
					+ " WHERE user = ? AND id = ? ; ");
			cStmt.setObject(1, response);
			cStmt.setString(2, username);
			cStmt.setInt(3, id);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

}
src/main/java/org/remitt/datastore/UserManagement.java
public class UserManagement {

	static final Logger log = Logger.getLogger(UserManagement.class);

	public static final String SQL_GET_USER = "SELECT "
			+ " u.username AS username " + " , u.contactemail AS contactemail "
			+ " , u.callbackserviceuri AS callbackserviceuri "
			+ " , u.callbackservicewsdluri AS callbackservicewsdluri "
			+ " , u.callbackusername AS callbackusername"
			+ " , u.callbackpassword AS callbackpassword "
			+ " , GROUP_CONCAT(r.rolename) AS roles " + " FROM tUser u "
			+ " LEFT OUTER JOIN tRole r ON r.username = u.username "
			+ " WHERE u.username = ? " + " GROUP BY u.username " + " LIMIT 1 "
			+ ";";

	public static final String SQL_LIST_USERS = "SELECT "
			+ " u.username AS username " + " , u.contactemail AS contactemail "
			+ " , u.callbackserviceuri AS callbackserviceuri "
			+ " , u.callbackservicewsdluri AS callbackservicewsdluri "
			+ " , u.callbackusername AS callbackusername"
			+ " , u.callbackpassword AS callbackpassword "
			+ " , GROUP_CONCAT(r.rolename) AS roles " + " FROM tUser u "
			+ " LEFT OUTER JOIN tRole r ON r.username = u.username "
			+ " GROUP BY u.username " + ";";

	public UserManagement() {
	}

	/**
	 * Add REMITT user with "default" role.
	 * 
	 * @param username
	 * @param password
	 * @param callbackServiceUri
	 * @param callbackServiceWsdlUri
	 * @param callbackUsername
	 * @param callbackPassword
	 * @return Success.
	 */
	public static boolean addUser(String username, String password,
			String callbackServiceUri, String callbackServiceWsdlUri,
			String callbackUsername, String callbackPassword) {
		Connection c = Configuration.getConnection();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("INSERT INTO tUser "
					+ " (  username, passhash, "
					+ " callbackserviceuri, callbackservicewsdluri, "
					+ " callbackusername, callbackpassword ) "
					+ " VALUES ( ?, MD5(?), ?, ?, ?, ? ) " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, password);
			cStmt.setString(3, callbackServiceUri);
			cStmt.setString(4, callbackServiceWsdlUri);
			cStmt.setString(5, callbackUsername);
			cStmt.setString(6, callbackPassword);
			cStmt.execute();
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
			return false;
		} catch (Throwable e) {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
			return false;
		}

		boolean status = false;
		PreparedStatement cStmt2 = null;
		try {
			cStmt2 = c.prepareStatement("INSERT INTO tRole "
					+ " ( username, rolename ) " + " VALUES ( ?, ? ) " + ";");
			cStmt2.setString(1, username);
			cStmt2.setString(2, "default");
			cStmt2.execute();
			c.close();
			status = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error(e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return status;
	}

	/**
	 * Retrieve a single <UserDTO> object for a named user.
	 * 
	 * @param username
	 * @return User object.
	 */
	public static UserDTO getUser(String username) {
		Connection c = Configuration.getConnection();

		UserDTO ret = new UserDTO();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement(SQL_GET_USER);
			log.debug(SQL_GET_USER + " with param " + username);
			cStmt.setString(1, username);
			cStmt.execute();
			ResultSet rs = cStmt.getResultSet();
			rs.next();
			ret.setUsername(rs.getString(1));
			ret.setContactEmail(rs.getString(2));
			ret.setCallbackServiceUri(rs.getString(3));
			ret.setCallbackServiceWsdlUri(rs.getString(4));
			ret.setCallbackUsername(rs.getString(5));
			ret.setCallbackPassword(rs.getString(6));
			ret.setRoles(rs.getString(7).split(","));
			rs.close();
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error(e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

	/**
	 * Get list of all users in the system.
	 * 
	 * @return List of user objects.
	 */
	public static List<UserDTO> listUsers() {
		Connection c = Configuration.getConnection();

		List<UserDTO> ret = new ArrayList<UserDTO>();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement(SQL_LIST_USERS);
			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				while (rs.next()) {
					UserDTO u = new UserDTO();
					u.setUsername(rs.getString("username"));
					u.setContactEmail(rs.getString("contactemail"));
					u.setCallbackServiceUri(rs.getString("callbackserviceuri"));
					u.setCallbackServiceWsdlUri(rs
							.getString("callbackservicewsdluri"));
					u.setCallbackUsername(rs.getString("callbackusername"));
					u.setCallbackPassword(rs.getString("callbackpassword"));
					u.setRoles(rs.getString("roles").split(","));
					ret.add(u);
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

}
src/main/java/org/remitt/prototype/PluginInterface.java
public interface PluginInterface {

	public String getPluginName();

	public Double getPluginVersion();

	public String getInputFormat();

	public String getOutputFormat();

	public HashMap<String, String> getOptions();

	public byte[] render(Integer jobId, byte[] input, String option)
			throws Exception;

	public String[] getPluginConfigurationOptions();

	public void setDefaultUsername(String username);

}
src/main/java/org/remitt/prototype/ConfigurationOption.java
public class ConfigurationOption {

	private String namespace;
	private String name;
	private String value;

	public ConfigurationOption() {
	}

	public ConfigurationOption(String namespace, String name, String value) {
		this.setNamespace(namespace);
		this.setName(name);
		this.setValue(value);
	}

	/**
	 * @param namespace
	 *            the namespace to set
	 */
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	/**
	 * @return the namespace
	 */
	public String getNamespace() {
		return namespace;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param value
	 *            the value to set
	 */
	public void setValue(String value) {
		this.value = value;
	}

	/**
	 * @return the value
	 */
	public String getValue() {
		return value;
	}

}
src/main/java/org/remitt/prototype/ValidationInterface.java
public interface ValidationInterface {

	public String getPluginName();

	public Double getPluginVersion();

	public ValidationResponse validate(String userName, byte[] input)
			throws Exception;

	public String[] getPluginConfigurationOptions();

}
src/main/java/org/remitt/prototype/EligibilityResponse.java
public class EligibilityResponse implements Serializable {

	private static final long serialVersionUID = 80195456387213L;

	private EligibilityStatus status;
	private EligibilitySuccessCode successCode;
	private String rawResponse;
	private String[] messages;

	public EligibilityResponse() {
	}

	public String[] getMessages() {
		return messages;
	}

	public void setMessages(String[] m) {
		messages = m;
	}

	public String getRawResponse() {
		return rawResponse;
	}

	public void setRawResponse(String r) {
		rawResponse = r;
	}

	public EligibilityStatus getStatus() {
		return status;
	}

	public void setStatus(EligibilityStatus s) {
		status = s;
	}

	public EligibilitySuccessCode getSuccessCode() {
		return successCode;
	}

	public void setSuccessCode(EligibilitySuccessCode s) {
		successCode = s;
	}
}
src/main/java/org/remitt/server/Configuration.java
public class Configuration {

	public static String DEFAULT_CONFIG = "/WEB-INF/remitt.properties";
	public static String OVERRIDE_CONFIG = System.getProperty("remitt.properties");

	static final Logger log = Logger.getLogger(Configuration.class);

	protected static CompositeConfiguration compositeConfiguration = null;

	protected static HttpServlet servletContext = null;

	protected static ControlThread controlThread = null;

	protected static ComboPooledDataSource comboPooledDataSource = null;

	protected static Scheduler scheduler = null;

	/**
	 * Get servlet object.
	 * 
	 * @return
	 */
	public static HttpServlet getServletContext() {
		return servletContext;
	}

	/**
	 * Store servlet object.
	 * 
	 * @param hS
	 */
	public static void setServletContext(HttpServlet hS) {
		servletContext = hS;
	}

	/**
	 * Get current global configuration object.
	 * 
	 * @return
	 */
	public static CompositeConfiguration getConfiguration() {
		if (compositeConfiguration == null) {
			Configuration.loadConfiguration();
		}
		if (compositeConfiguration == null) {
			log
					.error("Should never be null here, configuration is failing to load!");
		}
		return compositeConfiguration;
	}

	/**
	 * Load configuration from both template and override properties files.
	 */
	public static void loadConfiguration() {
		log.trace("Entered loadConfiguration");
		if (compositeConfiguration == null) {
			log.info("Configuration object not present, instantiating");
			compositeConfiguration = new CompositeConfiguration();

			PropertiesConfiguration defaults = null;
			try {
				log
						.info("Attempting to create PropertiesConfiguration object for DEFAULT_CONFIG");
				defaults = new PropertiesConfiguration(servletContext
						.getServletContext().getRealPath(DEFAULT_CONFIG));
				log.info("Loading default configuration from "
						+ servletContext.getServletContext().getRealPath(
								DEFAULT_CONFIG));
				defaults.load();
			} catch (ConfigurationException e) {
				log.error("Could not load default configuration from "
						+ servletContext.getServletContext().getRealPath(
								DEFAULT_CONFIG));
				log.error(e);
			}
			if (OVERRIDE_CONFIG != null) {
				PropertiesConfiguration overrides = null;
				try {
					log
							.info("Attempting to create PropertiesConfiguration object for OVERRIDE_CONFIG");
					overrides = new PropertiesConfiguration();
					log.info("Setting file for OVERRIDE_CONFIG");
					overrides.setFile(new File(OVERRIDE_CONFIG));
					log.info("Setting reload strategy for OVERRIDE_CONFIG");
					overrides
							.setReloadingStrategy(new FileChangedReloadingStrategy());
					log.info("Loading OVERRIDE_CONFIG");
					overrides.load();
				} catch (ConfigurationException e) {
					log.error("Could not load overrides", e);
				} catch (Exception ex) {
					log.error(ex);
				}
				if (overrides != null) {
					compositeConfiguration.addConfiguration(overrides);
				}
			}
			// Afterwards, add defaults so they're read second.
			compositeConfiguration.addConfiguration(defaults);
		}
	}

	public static void setControlThread(ControlThread ct) {
		controlThread = ct;
	}

	public static ControlThread getControlThread() {
		return controlThread;
	}

	/**
	 * Attempt to find the current installed location of REMITT. First tries
	 * "REMITT_HOME" environment variable, then attempts to use the
	 * catalina.home property.
	 * 
	 * @return
	 */
	public static String getInstallLocation() {
		String home = System.getenv("REMITT_HOME");
		home = (home == null || home == "") ? System
				.getProperty("catalina.home") : home;
		home = (home == null || home == "") ? System.getProperty("jetty.home")
				: home;
		return home;
	}

	/**
	 * Get an unused database connection from the <ComboPooledDataSource> pool
	 * of db connections.
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		try {
			return comboPooledDataSource.getConnection();
		} catch (SQLException e) {
			log.error(e);
			return null;
		}
	}

	public static ComboPooledDataSource getComboPooledDataSource() {
		return comboPooledDataSource;
	}

	public static void setComboPooledDataSource(ComboPooledDataSource c) {
		comboPooledDataSource = c;
	}

	/**
	 * Resolve plugin name for translation plugin to be used with render and
	 * transport plugins and their respective parameters.
	 * 
	 * @param renderPlugin
	 *            Full class name of the render plugin being used
	 * @param renderOption
	 *            Name of the render option being passed
	 * @param transportPlugin
	 *            Full class name of the transport plugin being used
	 * @param transportOption
	 *            Option name of the transport plugin being passed
	 * @return Full class name of the appropriate translation plugin, or null if
	 *         none is available.
	 */
	public static String resolveTranslationPlugin(String renderPlugin,
			String renderOption, String transportPlugin, String transportOption) {
		log.info("resolveTranslationPlugin: " + renderPlugin + ", "
				+ renderOption + ", " + transportPlugin + ", "
				+ (transportOption == null ? "" : transportOption));

		Connection c = Configuration.getConnection();
		CallableStatement cStmt = null;
		String ret = null;
		try {
			cStmt = c
					.prepareCall("CALL p_ResolveTranslationPlugin( ?, ?, ?, ? );");
			cStmt.setString(1, renderPlugin);
			cStmt.setString(2, renderOption);
			cStmt.setString(3, transportPlugin);
			cStmt.setString(4, transportOption);

			boolean hasResult = cStmt.execute();
			if (hasResult) {
				ResultSet r = cStmt.getResultSet();
				r.next();
				ret = r.getString(1);
				log.info("Resolved to class : " + ret);
				DbUtil.closeSafely(r);
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

	/**
	 * Get a list of plugins for a particular category.
	 * 
	 * @param category
	 * @return
	 */
	public static List<String> getPlugins(String category) {
		List<String> results = new ArrayList<String>();

		if (category.equalsIgnoreCase("validation")) {
			category = "validation"; // validation
		} else if (category.equalsIgnoreCase("render")) {
			category = "render"; // render
		} else if (category.equalsIgnoreCase("translation")) {
			category = "translation"; // translation
		} else if (category.equalsIgnoreCase("transport")) {
			category = "transport"; // transport
		} else if (category.equalsIgnoreCase("eligibility")) {
			category = "eligibility"; // eligibility
		} else if (category.equalsIgnoreCase("scooper")) {
			category = "scooper"; // scooper
		} else {
			// No plugins for dud categories.
			log.error("Could not find plugins for category " + category);
			return results;
		}

		Connection c = getConnection();

		PreparedStatement cStmt = null;
		try {
			log.debug("SELECT * FROM tPlugins " + "WHERE category = "
					+ category);

			cStmt = c.prepareStatement("SELECT * FROM tPlugins "
					+ "WHERE category = ?");

			cStmt.setString(1, category);

			boolean hadResults = cStmt.execute();
			if (hadResults) {
				ResultSet rs = cStmt.getResultSet();
				while (rs.next()) {
					results.add(rs.getString("plugin"));
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return results;
	}

	/**
	 * Retrieve user-set configuration option for a particular plugin namespace.
	 * 
	 * @param plugin
	 *            Fully qualified class name with path (example:
	 *            "org.remitt.plugin.render.XsltPlugin")
	 * @param userName
	 *            Corresponds to username field in tUser table.
	 * @param option
	 *            Option string name.
	 * @return
	 */
	public static String getPluginOption(Object plugin, String userName,
			String option) {
		Connection c = getConnection();
		String className = plugin.getClass().getName();

		if (!(plugin instanceof PluginInterface)
				&& !(plugin instanceof EligibilityInterface)) {
			log.error("Could not resolve plugin");
			return null;
		}

		PreparedStatement cStmt = null;
		String ret = null;
		try {
			cStmt = c.prepareStatement("SELECT cValue FROM tUserConfig WHERE "
					+ " cNamespace=? AND user=? AND cOption=?;");

			cStmt.setString(1, className);
			cStmt.setString(2, userName);
			cStmt.setString(3, option);
			boolean hasResult = cStmt.execute();
			if (hasResult) {
				ResultSet r = cStmt.getResultSet();
				r.next();
				ret = r.getString(1);
				DbUtil.closeSafely(r);
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
			log.info("Statement: SELECT cValue FROM tUserConfig WHERE "
					+ "cNameSpace = '" + className + "' AND user = '"
					+ userName + "' AND cOption = " + option);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}
		return ret;
	}

	/**
	 * Get all configuration values for a user.
	 * 
	 * @param username
	 * @return
	 */
	public static ConfigurationOption[] getConfigValues(String username) {
		List<ConfigurationOption> results = new ArrayList<ConfigurationOption>();
		Connection c = Configuration.getConnection();
		PreparedStatement pStmt = null;
		try {
			pStmt = c.prepareStatement("SELECT * FROM tUserConfig "
					+ " WHERE user = ?");
			pStmt.setString(1, username);
			boolean hasResult = pStmt.execute();
			if (hasResult) {
				ResultSet rs = pStmt.getResultSet();
				while (!rs.isAfterLast()) {
					rs.next();
					ConfigurationOption item = new ConfigurationOption(rs
							.getString("cNamespace"), rs.getString("cOption"),
							rs.getString("cValue"));
					results.add(item);
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(pStmt);
			DbUtil.closeSafely(c);
		}
		return results.toArray(new ConfigurationOption[0]);
	}

	/**
	 * Set the configuration value for an option.
	 * 
	 * @param user
	 * @param namespace
	 * @param option
	 * @param value
	 */
	public static void setConfigValue(String user, String namespace,
			String option, String value) {
		log.info("setConfigValue: " + user + ", " + namespace + ", " + option
				+ ", " + value);

		Connection c = Configuration.getConnection();
		CallableStatement cStmt = null;
		try {
			cStmt = c.prepareCall("{ CALL p_UserConfigUpdate( ?, ?, ?, ? ); }");
			cStmt.setString(1, user);
			cStmt.setString(2, namespace);
			cStmt.setString(3, option);
			cStmt.setString(4, value);

			cStmt.execute();
			cStmt.getResultSet();
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}
	}

	/**
	 * Get list of previously scooped files.
	 * 
	 * @param username
	 *            Username of user running scooper
	 * @param pluginClass
	 *            Fully qualified scooper class name
	 * @param host
	 *            Host name
	 * @param path
	 *            SFTP path to files
	 * @return
	 */
	public static List<String> getScoopedFiles(String username,
			String pluginClass, String host, String path) {
		List<String> results = new ArrayList<String>();
		Connection c = Configuration.getConnection();
		PreparedStatement pStmt = null;
		try {
			pStmt = c.prepareStatement("SELECT filename, stamp FROM tScooper "
					+ " WHERE scooperClass = ? AND user = ? "
					+ " AND host = ? AND path = ?");
			pStmt.setString(1, pluginClass);
			pStmt.setString(2, username);
			pStmt.setString(3, host);
			pStmt.setString(4, path);
			boolean hasResult = pStmt.execute();
			if (hasResult) {
				ResultSet rs = pStmt.getResultSet();
				while (!rs.isAfterLast()) {
					rs.next();
					results.add(rs.getString("filename"));
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(pStmt);
			DbUtil.closeSafely(c);
		}
		return results;
	}

	/**
	 * Record scooped file.
	 * 
	 * @param scooperClass
	 * @param user
	 * @param host
	 * @param path
	 * @param filename
	 * @param content
	 * @return
	 */
	public static Integer addScoopedFile(String scooperClass, String user,
			String host, String path, String filename, byte[] content) {
		Connection c = Configuration.getConnection();

		PreparedStatement cStmt = null;
		Integer ret = null;
		try {
			cStmt = c.prepareStatement("INSERT INTO tScooper ( "
					+ " scooperClass, user, host, path, filename, content "
					+ " ) VALUES ( " + "?, ?, ?, ?, ?, ? " + " );",
					PreparedStatement.RETURN_GENERATED_KEYS);

			cStmt.setString(1, scooperClass);
			cStmt.setString(2, user);
			cStmt.setString(3, host);
			cStmt.setString(4, path);
			cStmt.setString(5, filename);
			cStmt.setBytes(6, content);

			cStmt.execute();
			ResultSet newKey = cStmt.getGeneratedKeys();
			ret = newKey.getInt("id");
			DbUtil.closeSafely(newKey);
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}
		return ret;
	}

	/**
	 * Push a remittance payload obtained from a scooper back to the
	 * "callback url" specified for the user who owns the payload.
	 * 
	 * @param scooperId
	 */
	public static void pushScoopedData(Integer scooperId) {
		Connection c = Configuration.getConnection();

		String user = null;
		byte[] content = null;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT "
					+ " user, host, path, filename, content"
					+ " FROM tScooper AS a " + " WHERE id = ? " + ";");
			cStmt.setInt(1, scooperId);

			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				rs.next();
				user = rs.getString(1);
				content = rs.getBytes(5);
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		// Bomb the hell out if we somehow fail.
		if (user == null || content == null) {
			log.error("Unable to pull scooper content for id = "
					+ scooperId.toString());
			return;
		}

		X12Message835 parser = new X12Message835();
		String parsedMessage = null;
		try {
			parser.parse(new String(content));
			parsedMessage = parser.getRemittance().toString();
		} catch (FormatException e) {
			log.error(e);
			return;
		}
		if (parsedMessage == null) {
			log.error("Null message, cannot process any further");
			return;
		}

		UserDTO u = UserManagement.getUser(user);
		pushDataCallback(u, content);
	}

	public static void pushRemittanceData(String username, byte[] content) {
		X12Message835 parser = new X12Message835();
		String parsedMessage = null;
		try {
			parser.parse(new String(content));
			parsedMessage = parser.getRemittance().toString();
		} catch (FormatException e) {
			log.error(e);
			return;
		}
		if (parsedMessage == null) {
			log.error("Null message, cannot process any further");
			return;
		}

		UserDTO u = UserManagement.getUser(username);
		pushDataCallback(u, parsedMessage.getBytes());
	}

	private static void pushDataCallback(UserDTO u, byte[] content) {
		RemittCallback_Service locator = new RemittCallback_ServiceLocator();
		RemittCallback_PortType service = null;

		String serviceUrl = u.getCallbackServiceUri();
		log.debug("pushDataCallback(): Using callback service URI : "
				+ u.getCallbackServiceUri());
		try {
			service = locator.getRemittCallbackSOAP(new URL(serviceUrl));
		} catch (ServiceException e) {
			log.error(e);
			return;
		} catch (MalformedURLException e) {
			log.error(e);
			return;
		}

		// Override with basic authentication for callback
		((Stub) service).setUsername(u.getCallbackUsername());
		((Stub) service).setPassword(u.getCallbackPassword());
		((Stub) service)._setProperty(Call.USERNAME_PROPERTY, u
				.getCallbackUsername());
		((Stub) service)._setProperty(Call.PASSWORD_PROPERTY, u
				.getCallbackPassword());

		log
				.info("pushDataCallback(): TODO: Need to pull original reference from payloads to pass back");
		int response = -1;
		try {
			response = service
					.sendRemittancePayload(0, "", new String(content));
		} catch (RemoteException e) {
			log.error(e);
		}
		log.info("pushDataCallback(): received response of " + response);
	}

	/**
	 * Get a constructed file name based on the jobId presented with a
	 * particular file extension.
	 * 
	 * @param jobId
	 * @param fileExtension
	 * @return
	 */
	public static String getFileName(Integer jobId, String fileExtension) {
		return jobId.toString() + "-" + System.currentTimeMillis() + "."
				+ fileExtension;
	}

	/**
	 * Get scheduler object.
	 * 
	 * @return
	 */
	public static Scheduler getScheduler() {
		return scheduler;
	}

	/**
	 * Store scheduler object.
	 * 
	 * @param s
	 */
	public static void setScheduler(Scheduler s) {
		scheduler = s;
	}

	/**
	 * Get <List<String>> of users who have a certain scooper enabled.
	 * 
	 * @param scooperEnabledConfigOption
	 * @return
	 */
	public static List<String> getUsersForScooper(
			String scooperEnabledConfigOption) {
		List<String> results = new ArrayList<String>();
		Connection c = Configuration.getConnection();
		PreparedStatement pStmt = null;
		try {
			pStmt = c.prepareStatement("SELECT user FROM tUserConfig "
					+ " WHERE cNamespace = ? "
					+ " AND cValue IN ( '1', 'yes', 'true' );");
			pStmt.setString(1, scooperEnabledConfigOption);
			boolean hasResult = pStmt.execute();
			if (hasResult) {
				ResultSet rs = pStmt.getResultSet();
				while (rs.next()) {
					results.add(rs.getString(1));
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(pStmt);
			DbUtil.closeSafely(c);
		}
		return results;
	}

}
src/main/java/org/remitt/prototype/FileListingItem.java
public class FileListingItem implements Serializable {

	private static final long serialVersionUID = 20100405145800L;

	private String filename;
	private Integer filesize;
	private Date inserted;
	private String originalId;

	public FileListingItem() {
	}

	public void setFilename(String filename) {
		this.filename = filename;
	}

	public String getFilename() {
		return filename;
	}

	public void setFilesize(Integer filesize) {
		this.filesize = filesize;
	}

	public Integer getFilesize() {
		return filesize;
	}

	public void setInserted(Date inserted) {
		this.inserted = inserted;
	}

	public Date getInserted() {
		return inserted;
	}

	public void setOriginalId(String originalId) {
		this.originalId = originalId;
	}

	public String getOriginalId() {
		return originalId;
	}

}
src/main/java/org/remitt/prototype/UserDTO.java
public class UserDTO implements Serializable {

	private static final long serialVersionUID = 2010032100000L;

	private String username;
	private String password;
	private String contactEmail;
	private String callbackServiceUri;
	private String callbackServiceWsdlUri;
	private String callbackUsername;
	private String callbackPassword;
	private String[] roles;

	public UserDTO() {
	}

	@Override
	public String toString() {
		return "UserDTO object [" + getUsername() + ", roles = "
				+ StringUtils.join(getRoles(), ',') + "]";
	}

	/**
	 * @param username
	 *            the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param contactEmail
	 *            the contactEmail to set
	 */
	public void setContactEmail(String contactEmail) {
		this.contactEmail = contactEmail;
	}

	/**
	 * @return the contactEmail
	 */
	public String getContactEmail() {
		return contactEmail;
	}

	/**
	 * @param callbackServiceUri
	 *            the callbackServiceUri to set
	 */
	public void setCallbackServiceUri(String callbackServiceUri) {
		this.callbackServiceUri = callbackServiceUri;
	}

	/**
	 * @return the callbackServiceUri
	 */
	public String getCallbackServiceUri() {
		return callbackServiceUri;
	}

	/**
	 * @param callbackServiceWsdlUri
	 *            the callbackServiceWsdlUri to set
	 */
	public void setCallbackServiceWsdlUri(String callbackServiceWsdlUri) {
		this.callbackServiceWsdlUri = callbackServiceWsdlUri;
	}

	/**
	 * @return the callbackServiceWsdlUri
	 */
	public String getCallbackServiceWsdlUri() {
		return callbackServiceWsdlUri;
	}

	/**
	 * @param callbackUsername
	 *            the callbackUsername to set
	 */
	public void setCallbackUsername(String callbackUsername) {
		this.callbackUsername = callbackUsername;
	}

	/**
	 * @return the callbackUsername
	 */
	public String getCallbackUsername() {
		return callbackUsername;
	}

	/**
	 * @param callbackPassword
	 *            the callbackPassword to set
	 */
	public void setCallbackPassword(String callbackPassword) {
		this.callbackPassword = callbackPassword;
	}

	/**
	 * @return the callbackPassword
	 */
	public String getCallbackPassword() {
		return callbackPassword;
	}

	/**
	 * @param roles
	 *            the roles to set
	 */
	public void setRoles(String[] roles) {
		this.roles = roles;
	}

	/**
	 * @return the roles
	 */
	public String[] getRoles() {
		return roles;
	}

}
src/main/java/org/remitt/datastore/DbFileStore.java
public class DbFileStore {

	static final Logger log = Logger.getLogger(DbFileStore.class);

	public DbFileStore() {
	}

	/**
	 * Remove a file from database-backed file store.
	 * 
	 * @param username
	 * @param category
	 * @param filename
	 * @return Success.
	 */
	public static boolean deleteFile(String username, String category,
			String filename) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("DELETE FROM tFileStore "
					+ " WHERE user = ? " + " AND category = ? "
					+ " AND filename = ?" + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, category);
			cStmt.setString(3, filename);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

	/**
	 * Create new "unique" filename.
	 * 
	 * @param extension
	 * @return String representation of the filename.
	 */
	public static synchronized String generateFilename(String extension) {
		return new Long(System.currentTimeMillis()).toString() + "."
				+ extension;
	}

	/**
	 * Retrieve file contents from database-backed file store.
	 * 
	 * @param username
	 * @param category
	 * @param file
	 * @return Contents of file.
	 */
	public static byte[] getFile(String username, String category, String file) {
		Connection c = Configuration.getConnection();

		byte[] ret = null;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT content FROM tFileStore "
					+ " WHERE user = ? AND category = ? and filename = ? "
					+ ";");
			cStmt.setString(1, username);
			cStmt.setString(2, category);
			cStmt.setString(3, file);

			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				rs.next();
				ret = rs.getBytes("content");
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

	/**
	 * Insert file into database-backed file store. Duplicates throw SQL errors,
	 * since the db backed file store has a constraint specifying a unique index
	 * for the file names.
	 * 
	 * @param username
	 * @param category
	 * @param filename
	 * @param content
	 * @return Success, true or false.
	 */
	public static boolean putFile(String username, String category,
			String filename, byte[] content, Integer processorId) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		Integer payloadId = 0;
		try {
			payloadId = Configuration.getControlThread()
					.getPayloadFromProcessor(processorId).getId();
		} catch (Exception ex) {
			log.error("Couldn't get payloadId from processorId = "
					+ (processorId == null ? "null" : processorId));
		}

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("INSERT INTO tFileStore "
					+ " ( user, stamp, category, filename, content, "
					+ " contentsize, processorId, payloadId ) "
					+ " VALUES ( ?, NOW(), ?, ?, ?, ?, ?, ? ) " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, category);
			cStmt.setString(3, filename);
			cStmt.setBytes(4, content);
			cStmt.setInt(5, content.length);
			cStmt.setInt(6, processorId);
			cStmt.setInt(7, payloadId);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

}
src/main/java/org/remitt/prototype/EligibilityRequest.java
public class EligibilityRequest implements Serializable {

	private static final long serialVersionUID = -7314219097240200502L;

	private String plugin;
	private Map<EligibilityParameter, String> request;

	public EligibilityRequest() {
	}

	public String getPlugin() {
		return plugin;
	}

	public void setPlugin(String plugin) {
		this.plugin = plugin;
	}

	public Map<EligibilityParameter, String> getRequest() {
		return request;
	}

	public void setRequest(Map<EligibilityParameter, String> request) {
		this.request = request;
	}

}
src/main/java/org/remitt/server/DbUtil.java
public class DbUtil {

	public static void closeSafely(Connection c) {
		if (c != null) {
			try {
				c.close();
			} catch (Exception ex) {
			}
		}
	}

	public static void closeSafely(PreparedStatement c) {
		if (c != null) {
			try {
				c.close();
			} catch (Exception ex) {
			}
		}
	}

	public static void closeSafely(CallableStatement c) {
		if (c != null) {
			try {
				c.close();
			} catch (Exception ex) {
			}
		}
	}

	public static void closeSafely(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (Exception ex) {
			}
		}
	}

}
src/main/java/org/remitt/prototype/ValidationResponse.java
public class ValidationResponse implements Serializable {

	private static final long serialVersionUID = 7874460334444969370L;

	private ValidationStatus status;
	private List<ValidationResponseMessage> messages = new ArrayList<ValidationResponseMessage>();

	public ValidationResponse() {
	}

	public List<ValidationResponseMessage> getMessages() {
		return messages;
	}

	public void setMessages(List<ValidationResponseMessage> messages) {
		this.messages = messages;
	}

	public void addMessage(ValidationResponseMessage message) {
		this.messages.add(message);
	}

	public void setStatus(ValidationStatus status) {
		this.status = status;
	}

	public ValidationStatus getStatus() {
		return status;
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).append("status", status).append(
				"messages", messages).toString();
	}

}
src/main/java/org/remitt/datastore/KeyringStore.java
public class KeyringStore {

	static final Logger log = Logger.getLogger(KeyringStore.class);

	public KeyringStore() {
	}

	/**
	 * Remove a key from a user's keyring.
	 * 
	 * @param username
	 * @param keyname
	 * @return Success.
	 */
	public static boolean deleteKey(String username, String keyname) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("DELETE FROM tKeyring "
					+ " WHERE user = ? " + " AND keyname = ? " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, keyname);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

	/**
	 * Get a key from a user's keyring.
	 * 
	 * @param username
	 *            User name
	 * @param keyname
	 *            Canonical key name
	 * @return Keyring item object.
	 */
	public static KeyringItem getKey(String username, String keyname) {
		Connection c = Configuration.getConnection();

		KeyringItem ret = null;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT " + " privatekey "
					+ " , publickey " + " FROM tKeyring "
					+ " WHERE user = ? AND keyname = ? " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, keyname);

			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				rs.next();
				ret = new KeyringItem();
				ret.setKeyname(keyname);
				ret.setPrivatekey(rs.getBytes(1));
				ret.setPublickey(rs.getBytes(2));
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

	/**
	 * Get keyring for user.
	 * 
	 * @param username
	 * @return All items on keyring as array.
	 */
	public static KeyringItem[] getKeys(String username) {
		Connection c = Configuration.getConnection();

		List<KeyringItem> ret = new ArrayList<KeyringItem>();

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT " + " keyname "
					+ ", privatekey " + " , publickey " + " FROM tKeyring "
					+ " WHERE user = ? " + ";");
			cStmt.setString(1, username);

			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				while (rs.next()) {
					KeyringItem i = new KeyringItem();
					i.setKeyname(rs.getString(1));
					i.setPrivatekey(rs.getBytes(2));
					i.setPublickey(rs.getBytes(3));
					ret.add(i);
				}
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret.toArray(new KeyringItem[0]);
	}

	/**
	 * Get a named public or private key from a user's keyring.
	 * 
	 * @param username
	 *            User name
	 * @param keyname
	 *            Canonical key name
	 * @param privateKey
	 *            Whether or not the key being requested is a private key. If
	 *            false, the public key will be returned.
	 * @return Contents of key.
	 */
	public static byte[] getKey(String username, String keyname,
			boolean privateKey) {
		Connection c = Configuration.getConnection();

		byte[] ret = null;

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT "
					+ (privateKey ? "privatekey" : "publickey")
					+ " FROM tKeyring " + " WHERE user = ? AND keyname = ? "
					+ ";");
			cStmt.setString(1, username);
			cStmt.setString(2, keyname);

			if (cStmt.execute()) {
				ResultSet rs = cStmt.getResultSet();
				rs.next();
				ret = rs.getBytes(1);
				rs.close();
			}
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return ret;
	}

	/**
	 * Add a key to the user's keyring.
	 * 
	 * @param username
	 * @param keyname
	 * @param privatekey
	 * @param publickey
	 * @return Success.
	 */
	public static boolean putKey(String username, String keyname,
			byte[] privatekey, byte[] publickey) {
		Connection c = Configuration.getConnection();

		boolean success = false;

		try {
			log.trace("Executing deleteKey so we don't have duplicates");
			deleteKey(username, keyname);
		} catch (Exception ex) {
			log.debug(ex);
		}

		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("INSERT INTO tKeyring "
					+ " ( user, keyname, privatekey, publickey ) "
					+ " VALUES ( ?, ?, ?, ? ) " + ";");
			cStmt.setString(1, username);
			cStmt.setString(2, keyname);
			cStmt.setBytes(3, privatekey);
			cStmt.setBytes(4, publickey);
			cStmt.execute();
			success = true;
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (Throwable e) {
			log.error("Caught Throwable", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}

		return success;
	}

}
src/main/java/org/remitt/prototype/ParserInterface.java
public interface ParserInterface {

	public String parseData(String inputData) throws Exception;

}
src/main/java/org/remitt/server/Service.java
@GZIP
@WebService(targetNamespace = "http://server.remitt.org/")
public interface Service {

	/**
	 * Get version number of REMITT protocol being used.
	 * 
	 * @return String representation of protocol version.
	 */
	public String getProtocolVersion();

	/**
	 * Change current user's password
	 * 
	 * @param newPassword
	 *            New password
	 * @return Success
	 */
	public Boolean changePassword(
			@PathParam("pw") @WebParam(name = "pw") String newPassword);

	/**
	 * Get the currently authenticated user's name.
	 * 
	 * @return String representation of the user's name.
	 */
	public String getCurrentUserName();

	/**
	 * Insert payload into the system for processing.
	 * 
	 * @param originalId
	 *            Foreign system id for this payload
	 * @param inputPayload
	 *            XML text payload
	 * @param renderPlugin
	 *            Fully qualified Java class name of rendering plugin.
	 * @param renderOption
	 *            Optional option for render plugin.
	 * @param transportPlugin
	 *            Fully qualified Java class name of transport plugin
	 * @param transportOption
	 *            Optional option for the transport plugin
	 * @return tPayload unique identifier for this job.
	 */
	public Integer insertPayload(
			@PathParam("originalId") @WebParam(name = "originalId") String originalId,
			@PathParam("inputPayload") @WebParam(name = "inputPayload") String inputPayload,
			@PathParam("renderPlugin") @WebParam(name = "renderPlugin") String renderPlugin,
			@PathParam("renderOption") @WebParam(name = "renderOption") String renderOption,
			@PathParam("transportPlugin") @WebParam(name = "transportPlugin") String transportPlugin,
			@PathParam("transportOption") @WebParam(name = "transportOption") String transportOption);

	/**
	 * Resubmit an existing payload.
	 * 
	 * @param originalPayloadId
	 *            tPayload unique identifier for the original payload.
	 * @return New tPayload unique identifier for this job.
	 */
	public Integer resubmitPayload(
			@PathParam("originalPayloadId") @WebParam(name = "originalPayloadId") Integer originalPayloadId);

	/**
	 * Get all configuration values for a user.
	 * 
	 * @return
	 */
	public ConfigurationOption[] getConfigValues();

	/**
	 * Set configuration option.
	 * 
	 * @param namespace
	 *            Fully qualified class name of plugin.
	 * @param option
	 *            Option key.
	 * @param value
	 *            Option value.
	 * @return Success.
	 */
	public Boolean setConfigValue(
			@PathParam("namespace") @WebParam(name = "namespace") String namespace,
			@PathParam("option") @WebParam(name = "option") String option,
			@PathParam("value") @WebParam(name = "value") String value);

	/**
	 * Retrieve current job status
	 * 
	 * @param jobId
	 * @return Integer indicating current status. 0 = completed, 1 =
	 *         verification, 2 = rendering, 3 = translation, 4 = transport, 5 =
	 *         unknown, 6 = failed
	 */
	public Integer getStatus(
			@PathParam("jobId") @WebParam(name = "jobId") Integer jobId);

	/**
	 * Retrieve current job status for a list of job ids.
	 * 
	 * @param jobIds
	 *            Array of payload ids.
	 * @return Array of Integers indicating current status. 0 = completed, 1 =
	 *         verification, 2 = rendering, 3 = translation, 4 = transport, 5 =
	 *         unknown
	 */
	public Integer[] getBulkStatus(
			@PathParam("jobIds") @WebParam(name = "jobIds") Integer[] jobIds);

	/**
	 * Retrieve list of file names that match the provided criteria.
	 * 
	 * @param category
	 * @param criteria
	 * @param value
	 * @return
	 */
	public FileListingItem[] getFileList(
			@PathParam("category") @WebParam(name = "category") String category,
			@PathParam("criteria") @WebParam(name = "criteria") String criteria,
			@PathParam("value") @WebParam(name = "value") String value);

	/**
	 * Get list of plugins for a specified category.
	 * 
	 * @param category
	 * @return
	 */
	public String[] getPlugins(
			@PathParam("category") @WebParam(name = "category") String category);

	/**
	 * Retrieve output file.
	 * 
	 * @param category
	 *            Output file category.
	 * @param filename
	 *            Name of file to be retrieved.
	 * @return Contents of target file as byte array.
	 */
	public byte[] getFile(
			@PathParam("category") @WebParam(name = "category") String category,
			@PathParam("filename") @WebParam(name = "filename") String filename);

	/**
	 * Get list of years for which the system has output files.
	 * 
	 * @return
	 */
	public Integer[][] getOutputYears();

	/**
	 * Get list of months in a target year for which the system has output
	 * files.
	 * 
	 * @param targetYear
	 * @return
	 */
	public String[] getOutputMonths(
			@PathParam("targetyear") @WebParam(name = "targetYear") Integer targetYear);

	/**
	 * Get list of plugin options.
	 * 
	 * @param pluginClass
	 *            Fully qualified class name of target plugin.
	 * @param qualifyingOption
	 *            Optional qualifier, required by render plugin.
	 * @return
	 */
	public String[] getPluginOptions(
			@PathParam("pluginclass") @WebParam(name = "pluginclass") String pluginClass,
			@PathParam("qualifyingoption") @WebParam(name = "qualifyingoption") String qualifyingOption);

	/**
	 * Check for eligibility.
	 * 
	 * @param request
	 * @return
	 */
	public EligibilityResponse getEligibility(
			@PathParam("request") @WebParam(name = "request") EligibilityRequest request);

	/**
	 * Insert batches of eligibility checks.
	 * 
	 * @param requests
	 * @return
	 */
	public Integer batchEligibilityCheck(
			@PathParam("requests") @WebParam(name = "requests") EligibilityRequest[] requests);

	/**
	 * Use a REMITT parser to parse source data.
	 * 
	 * @param parserClass
	 *            <ParserInterface> descendent class name
	 * @param data
	 *            Raw data to be parsed
	 * @return
	 */
	public String parseData(
			@PathParam("parserClass") @WebParam(name = "parserClass") String parserClass,
			@PathParam("data") @WebParam(name = "data") String data);

	/**
	 * Validate an arbitrary
	 * 
	 * @param validatorClass
	 *            <ValidationPlugin> descendent class name
	 * @param data
	 *            Raw data to be validated.
	 * @return Payload describing validator output
	 */
	public ValidationResponse validatePayload(
			@PathParam("parserClass") @WebParam(name = "validatorClass") String validatorClass,
			@PathParam("data") @WebParam(name = "data") byte[] data);

	/**
	 * Add a REMITT user.
	 * 
	 * @param user
	 * @return
	 */
	public boolean addRemittUser(
			@PathParam("user") @WebParam(name = "user") UserDTO user);

	/**
	 * Get array of REMITT user objects.
	 * 
	 * @return
	 */
	public UserDTO[] listRemittUsers();

	/**
	 * Add an encryption key to the REMITT user's key ring.
	 * 
	 * @param keyname
	 * @param privatekey
	 * @param publickey
	 * @return
	 */
	public boolean addKeyToKeyring(
			@PathParam("keyname") @WebParam(name = "keyname") String keyname,
			@PathParam("privatekey") @WebParam(name = "privatekey") byte[] privatekey,
			@PathParam("publickey") @WebParam(name = "publickey") byte[] publickey);

}
src/main/java/org/remitt/prototype/EligibilityInterface.java
public interface EligibilityInterface {

	public String getPluginName();

	public Double getPluginVersion();

	public EligibilityResponse checkEligibility(String userName,
			Map<EligibilityParameter, String> values, boolean resubmission,
			Integer jobId) throws Exception;

	public String[] getPluginConfigurationOptions();

}


Question: import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.jaxws.context.WrappedMessageContext;
import org.apache.cxf.message.Message;
import org.apache.log4j.Logger;
import org.remitt.datastore.DbEligibilityJob;
import org.remitt.datastore.DbFileStore;
import org.remitt.datastore.KeyringStore;
import org.remitt.datastore.UserManagement;
import org.remitt.prototype.ConfigurationOption;
import org.remitt.prototype.EligibilityInterface;
import org.remitt.prototype.EligibilityRequest;
import org.remitt.prototype.EligibilityResponse;
import org.remitt.prototype.FileListingItem;
import org.remitt.prototype.ParserInterface;
import org.remitt.prototype.PluginInterface;
import org.remitt.prototype.UserDTO;
import org.remitt.prototype.ValidationInterface;
import org.remitt.prototype.ValidationResponse;
import org.remitt.server.Configuration;
import org.remitt.server.DbUtil;
import org.remitt.server.Service;
		log.debug("getOutputYears for " + userName);

		Integer[][] returnValue = null;
		PreparedStatement cStmt = null;
		try {
			cStmt = c.prepareStatement("SELECT "
					+ " DISTINCT(YEAR(stamp)) AS year "
					+ ", COUNT(YEAR(stamp)) AS c " + " FROM tFileStore "
					+ "WHERE user = ? " + " GROUP BY YEAR(stamp) " + ";");
			cStmt.setString(1, userName);

			boolean hadResults = cStmt.execute();
			List<Integer[]> results = new ArrayList<Integer[]>();
			if (hadResults) {
				ResultSet rs = cStmt.getResultSet();
				while (rs.next()) {
					List<Integer> atomicResult = new ArrayList<Integer>();
					atomicResult.add(rs.getInt(1));
					atomicResult.add(rs.getInt(2));
					results.add(atomicResult.toArray(new Integer[0]));
				}
				rs.close();
			}
			returnValue = results.toArray(new Integer[0][0]);
		} catch (NullPointerException npe) {
			log.error("Caught NullPointerException", npe);
		} catch (SQLException e) {
			log.error("Caught SQLException", e);
		} finally {
			DbUtil.closeSafely(cStmt);
			DbUtil.closeSafely(c);
		}
		return returnValue;
	}

	@POST
	@Path("eligibility")
	@Produces("application/json")
	@Override
	public EligibilityResponse getEligibility(EligibilityRequest request) {
		String userName = getCurrentUserName();

		EligibilityInterface p = null;
		try {
			p = (EligibilityInterface) Class.forName(request.getPlugin())
					.newInstance();
		} catch (InstantiationException e) {
			log.error(e);
			return null;
		} catch (IllegalAccessException e) {
			log.error(e);
			return null;
		} catch (ClassNotFoundException e) {
			log.error(e);
			return null;
		}
		try {
			return p.checkEligibility(userName, request.getRequest(), false,
					(int) System.currentTimeMillis() % 1000000000);
		} catch (Exception e) {
			log.error(e);
			return null;
		}
	}

	@POST
	@Path("eligibilitybatch")
	@Produces("application/json")
	@Override
	public Integer batchEligibilityCheck(EligibilityRequest[] requests) {
		String userName = getCurrentUserName();
		for (EligibilityRequest param : requests) {
			DbEligibilityJob.addEligibilityJob(userName, param.getPlugin(),
					param.getRequest());
		}
		return 1;
	}

	@POST
	@Path("parse")
	@Produces("application/json")
	@Override
	public String parseData(String parserClass, String data) {
		// String userName = getCurrentUserName();

		ParserInterface p = null;
		try {
			p = (ParserInterface) Class.forName(parserClass).newInstance();
		} catch (InstantiationException e) {
			log.error(e);
			return null;
		} catch (IllegalAccessException e) {
			log.error(e);
			return null;
		} catch (ClassNotFoundException e) {
			log.error(e);
			return null;
		}
		try {
			return p.parseData(data);
		} catch (Exception e) {
			log.error(e);
			return null;
		}
	}

	@POST
	@Path("addkey/{keyname}/{privatekey}/{publickey}")
	@Produces("application/json")
	@Override
	public boolean addKeyToKeyring(String keyname, byte[] privatekey,
			byte[] publickey) {
		return KeyringStore.putKey(getCurrentUserName(), keyname, privatekey,
				publickey);
	}

	@POST
	@Path("adduser/{user}")
	@Produces("application/json")
	@Override
Answer: 	public boolean addRemittUser(UserDTO user) {