package softarch.portal.app;


import softarch.portal.data.RawData;
import softarch.portal.data.RegularData;
import softarch.portal.data.UserProfile;
import softarch.portal.db.DbFacadeInterface;
import softarch.portal.db.json.Database;
import softarch.portal.db.sql.DatabaseFacade;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Date;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * This class implements a facade for all of the application layer's
 * functionality.
 * @author Niels Joncheere
 */
public class ApplicationFacade {
	private UserManager		userManager;
	private QueryManager		queryManager;
	private AdministrationManager	administrationManager;
	private OperationManager	operationManager;

	/**
	 * Creates a new application facade.
	 */
	public ApplicationFacade(	String dbUser,
					String dbPassword,
					String dbUrl) {
		//should be determined by config file
		
		DbFacadeInterface dbFacade
			= new DatabaseFacade(dbUser, dbPassword, dbUrl);
		
		userManager		= new UserManager(dbFacade);
		queryManager		= new QueryManager(dbFacade);
		administrationManager	= new AdministrationManager(dbFacade);
		operationManager	= new OperationManager(dbFacade);
	}
	
	public ApplicationFacade(String config) {
		try {
			DbFacadeInterface dbFacade = getDatabaseFacade(config);
			userManager		= new UserManager(dbFacade);
			queryManager		= new QueryManager(dbFacade);
			administrationManager	= new AdministrationManager(dbFacade);
			operationManager	= new OperationManager(dbFacade);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public DbFacadeInterface getDatabaseFacade(String configPath) throws Exception {
		JSONParser parser = new JSONParser();
		
			try {
				Object obj = parser.parse(new FileReader(configPath));
				JSONObject json = (JSONObject) obj;
				String facade = (String) json.get("name");
				JSONArray paramsArray = (JSONArray) json.get("parameters");
				Object[] params = paramsArray.toArray();
				
				Class<?> c = Class.forName(facade);
				Constructor<?> cons = c.getConstructor(String.class);
				DbFacadeInterface object = (DbFacadeInterface) cons.newInstance(params);
				return (DbFacadeInterface) object;
			} catch (Exception e) {
				throw new Exception(e.getMessage());
			} 
	}



	/**
	 * Adds a user profile to the user database.
	 * @param profile The profile to be added.
	 */
	public void add(UserProfile profile)
		throws ApplicationException {

		userManager.add(profile);
	}

	/**
	 * Returns the user profile for the user with the specified username.
	 */
	public UserProfile findUser(String username)
		throws ApplicationException {

		return userManager.findUser(username);
	}

	/**
	 * Returns the user profile for the user with the specified username,
	 * and throws an exception if his session ID does not match the one that
	 * is provided as a parameter.
	 */
	public UserProfile findUser(String username, Number sessionId)
		throws ApplicationException {

		return userManager.findUser(username, sessionId);
	}

	/**
	 * Logs in the user with the specified username and password.
	 */
	public Number login(String username, String password)
		throws ApplicationException {

		return userManager.login(username, password);
	}

	/**
	 * Returns a list of all users that are currently logged in.
	 */
	public List getActiveUsers()
		throws ApplicationException {

		return userManager.getActiveUsers();
	}

	/**
	 * Logs out the user with the specified username and session ID.
	 */
	public void logout(String username, Number sessionId)
		throws ApplicationException {

		userManager.logout(username, sessionId);
	}



	/**
	 * Returns a list containing all records of the given information type
	 * that match the given query string.
	 * @param informationType	The information type the user wants
	 * 				to query.
	 * @param queryString		The query string that should be used
	 * 				to carry out the search (for example
	 * 				"+foo -bar").
	 */
	public List findRecords(String informationType, String queryString)
		throws ApplicationException {

		return queryManager.findRecords(informationType, queryString);
	}

	/**
	 * Returns a list containing all records of the given information type
	 * that were added after the given date.
	 */
	public List findRecordsFrom(String informationType, Date date)
		throws ApplicationException {

		return queryManager.findRecordsFrom(informationType, date);
	}



	/**
	 * Adds a new regular data object to the regular database.
	 * @param rd	The regular data object that should be added to
	 * 		the regular database.
	 */
	public void add(RegularData rd)
		throws ApplicationException {

		administrationManager.add(rd);
	}

	/**
	 * Returns a list that contains all raw data that is currently stored
	 * in the raw database.
	 */
	public List getRawData()
		throws ApplicationException {

		return administrationManager.getRawData();
	}

	/**
	 * Returns a specific raw data object.
	 */
	public RawData getRawData(int id)
		throws ApplicationException {

		return administrationManager.getRawData(id);
	}

	/**
	 * Creates a new raw data object with an empty source.
	 * The structure of the object is specified by the <code>rd</code>
	 * parameter.
	 */
	public void addRawData(RegularData rd)
		throws ApplicationException {

		administrationManager.addRawData(rd);
	}

	/**
	 * Deletes a raw data object.
	 * @param rd	The raw data object that should be deleted.
	 */
	public void deleteRawData(RawData rd)
		throws ApplicationException {

		administrationManager.deleteRawData(rd);
	}

	/**
	 * Updates a raw data object.
	 * @param rd	The raw data object that should be updated.
	 */
	public void updateRawData(RawData rd)
		throws ApplicationException {

		administrationManager.updateRawData(rd);
	}



	/**
	 * Returns the number of records of the given information type in the
	 * regular database.
	 */
	public int getNumberOfRegularRecords(String informationType)
		throws ApplicationException {

		return operationManager.getNumberOfRegularRecords(informationType);
	}

	/**
	 * Returns the number of records in the raw database.
	 */
	public int getNumberOfRawRecords()
		throws ApplicationException {

		return operationManager.getNumberOfRawRecords();
	}
}

@@ -2273,16 +2273,167 @@
 ();%0A%09%09%09%09
+Class%5B%5D paramClasses = new Class%5Bparams.length%5D;%0A%09%09%09%09for (int i = 0; i %3C paramClasses.length; i++) %7B%0A%09%09%09%09%09paramClasses%5Bi%5D = params%5Bi%5D.getClass();%0A%09%09%09%09%7D
 %0A%09%09%09%09Cla
@@ -2512,20 +2512,20 @@
 tor(
-String.c
+paramC
 lass
+es
 );%0A%09

Update ApplicationFacade.java