Java tutorial
/* Name: - Application Description: - Requires: - Provides: - Part of: ProcessPuzzle Framework, Domain and Business Model Ready Architecture. Provides content, workflow and social networking functionality. http://www.processpuzzle.com ProcessPuzzle - Content and Workflow Management Integration Business Platform Author(s): - Zsolt Zsuffa Copyright: (C) 2011 This program 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. This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Created on Feb 12, 2006 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package com.processpuzzle.application.domain; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.configuration.HierarchicalConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import com.processpuzzle.application.configuration.domain.PersistentDataInitializationStrategies; import com.processpuzzle.application.configuration.domain.ProcessPuzzleApplicationComponent; import com.processpuzzle.application.configuration.domain.ProcessPuzzleContext; import com.processpuzzle.application.configuration.domain.PropertyContext; import com.processpuzzle.application.configuration.domain.PropertyContextOverrides; import com.processpuzzle.application.configuration.domain.PropertyKeys; import com.processpuzzle.application.resource.domain.DataLoader; import com.processpuzzle.application.resource.domain.HardCodedDataLoader; import com.processpuzzle.application.resource.domain.XmlDataLoader; import com.processpuzzle.application.security.domain.PredefinedUsersLoader; import com.processpuzzle.application.security.domain.User; import com.processpuzzle.application.security.domain.UserRepository; import com.processpuzzle.commons.persistence.AggregateRoot; import com.processpuzzle.fundamental_types.domain.GenericEntity; import com.processpuzzle.party.artifact.PredefinedUserDataSheetsCreator; import com.processpuzzle.persistence.domain.DefaultUnitOfWork; import com.processpuzzle.persistence.query.domain.DefaultQueryContext; import com.processpuzzle.user_session.domain.UserRequestManager; public abstract class Application extends GenericEntity<Application> implements AggregateRoot { private static final String PARAMETER_TYPE_ELEMENT_NAME = "type"; private static final String INSTANTIATION_ARGUMENTS_SELECTOR = "dl:instantiationArguments.dl:argument"; private static Logger log = LoggerFactory.getLogger(Application.class); protected ResourceLoader resourceLoader; protected String applicationName; protected String applicationVersion; protected String applicationDescription; protected ExecutionStatus executionStatus = ExecutionStatus.stopped; protected InstallationStatus installationStatus = InstallationStatus.notInstalled; protected ProcessPuzzleContext applicationContext; protected String configurationDescriptorPath = "classpath:com/itcodex/objectpuzzle/framework/configuration/domaintier/configuration_descriptor.xml"; protected Map<Application.Events, List<ApplicationEvent>> history = new LinkedHashMap<Events, List<ApplicationEvent>>(); protected List<DataLoader> dataLoaders = new ArrayList<DataLoader>(); // Constructors protected Application(String configurationDescriptorPath) { this(configurationDescriptorPath, new DefaultResourceLoader()); } protected Application(String configurationDescriptorPath, ResourceLoader resourceLoader) { this.configurationDescriptorPath = configurationDescriptorPath; this.resourceLoader = resourceLoader; defineApplicationDescription(); determineInstallationConfiguration(); determineInstallationStatus(); } public @Override @SuppressWarnings("unchecked") ApplicationIdentity getDefaultIdentity() { DefaultQueryContext context = new DefaultQueryContext(); context.addTextValueFor("applicationNameValue", applicationName); context.addTextValueFor("applicationVersionValue", applicationVersion); return new ApplicationIdentity(context); } // Public mutators public void install() throws ApplicationException { log.info("Installation of application: " + applicationName + " begins."); if (installationStatus.equals(InstallationStatus.installed)) throw new ReinstallationException(this); PropertyContextOverrides overrides = defineInstallationOverrides(); try { setUpApplicationContext(Action.install, overrides); applicationContext.createSystemInstallerRequestContext(this); persistSystemInstallerUser(); dataLoaders = determineDataLoaders(); executeDataLoaders(Action.install); executionStatus = ExecutionStatus.running; installationStatus = InstallationStatus.installed; addEventToHistory(Events.installed); } catch (Exception e) { throw new ApplicationInstallationException(this, e); } log.info("Installation of application: " + applicationName + " finished. \n"); } public void unInstall() { if (executionStatus == ExecutionStatus.running) stop(); log.info("Uninstallation of application: " + applicationName + " begins."); executionStatus = ExecutionStatus.stopped; installationStatus = InstallationStatus.notInstalled; log.info("Uninstallation of application: " + applicationName + " finished. \n"); } public void start() throws ApplicationException { start(null); } public void start(PropertyContextOverrides overrides) throws ApplicationException { if (executionStatus == ExecutionStatus.running) return; log.info("Starting of application: " + applicationName + " begins."); setUpApplicationContext(Action.start, overrides); executionStatus = ExecutionStatus.running; addEventToHistory(Events.started); log.info("Starting of application: " + applicationName + " ended."); } public void stop() { if (executionStatus == ExecutionStatus.stopped) return; applicationContext.tearDown(Action.stop); applicationContext = null; executionStatus = ExecutionStatus.stopped; log.info("Application stopped."); }; public User authenticateUser(String userName, String password) { UserRepository repository = (UserRepository) applicationContext.getRepository(UserRepository.class); DefaultUnitOfWork work = new DefaultUnitOfWork(true); User userInQuestion = repository.findUserByName(work, userName); if (userInQuestion != null && userInQuestion.getPassword().equals(password)) return userInQuestion; else return null; } public boolean loginUser(String userName, String password) { User user = authenticateUser(userName, password); if (user != null) return true; else return false; } // Public accessors public List<ApplicationEvent> findApplicationEventsByType(Events searchedEvent) { return history.get(searchedEvent); } @Override public boolean equals(Object objectToCheck) { if (!(objectToCheck instanceof Application)) return false; Application anotherApplication = (Application) objectToCheck; boolean returnValue = applicationName.equals(anotherApplication.applicationName) && applicationVersion.equals(anotherApplication.applicationVersion) && executionStatus.equals(anotherApplication.executionStatus) && installationStatus.equals(anotherApplication.installationStatus) && configurationDescriptorPath.equals(anotherApplication.configurationDescriptorPath) && applicationDescription.equals(anotherApplication.applicationDescription) && dataLoaders.equals(anotherApplication.dataLoaders); return returnValue; } // Collection facades public int getHistorySize() { return history.size(); } // Properties public String getApplicationName() { return applicationName; } public String getApplicationVersion() { return applicationVersion; } public String getConfigurationDescriptorPath() { return configurationDescriptorPath; } public ProcessPuzzleContext getContext() { return applicationContext; } public List<DataLoader> getDataLoaders() { return dataLoaders; } public String getDescription() { return applicationDescription; } public ExecutionStatus getExecutionStatus() { return executionStatus; } public InstallationStatus getInstallationStatus() { return installationStatus; } // Embeded enumerations public enum InstallationStatus { installed, notInstalled } public enum ExecutionStatus { stopped, running, suspended } public enum Events { started, stopped, installed, unistalled, dataload, backup, restore } public enum Action { install, uninstall, start, stop } // Protedted, private helper methods protected abstract void defineApplicationDescription(); protected void runDataLoader(String property) { String loaderClassName = (String) applicationContext.getProperty(property); if (loaderClassName != null) { try { DataLoader loader = (DataLoader) Class.forName(loaderClassName).newInstance(); loader.loadData(); } catch (Exception e) { e.printStackTrace(); throw new Error("The data loader: " + loaderClassName + " doesn't exist!"); } } } protected void addEventToHistory(Events eventName) { ApplicationEvent event = null; List<ApplicationEvent> eventList = history.get(eventName); if (eventList == null) eventList = new ArrayList<ApplicationEvent>(); switch (eventName) { case started: event = new ApplicationStartedEvent(); break; case stopped: event = new ApplicationStopped(); break; case installed: event = new ApplicationInstallationEvent(); break; case dataload: event = new DataLoadEvent(); break; case backup: event = new BackupEvent(); break; case restore: event = new RestoreEvent(); break; default: break; } eventList.add(event); history.put(eventName, eventList); } protected @Override void defineIdentityExpressions() { identities.add(getDefaultIdentity()); } private void addBusinessDefintionLoader(List<DataLoader> dataLoaders) { String path = null; try { path = determineBusinessDefintionsPaths(); XmlDataLoader businessDefinitionLoader = (XmlDataLoader) applicationContext .getBean(ProcessPuzzleApplicationComponent.BUSINESS_DEFINITION_LOADER.getComponentId()); businessDefinitionLoader.setResourcePath(path); dataLoaders.add(businessDefinitionLoader); } catch (NoSuchBeanDefinitionException e) { if (path != null && path != "") throw e; } } private void addPredefinedUsersDataSheetLoader(List<DataLoader> dataLoaders) { PredefinedUserDataSheetsCreator userDataSheetCreator = new PredefinedUserDataSheetsCreator( applicationContext); dataLoaders.add(userDataSheetCreator); } private void addPredefinedUsersLoader(List<DataLoader> dataLoaders) { PredefinedUsersLoader usersLoader = (PredefinedUsersLoader) applicationContext .getBean(ProcessPuzzleApplicationComponent.PREDEFINED_USERS_LOADER.getComponentId()); usersLoader.setApplicationContext(applicationContext); dataLoaders.add(usersLoader); } private void addSystemArtifactsLoader(List<DataLoader> dataLoaders) { String componentName = ProcessPuzzleApplicationComponent.SYSTEM_ARTIFACTS_LOADER.getComponentId(); try { HardCodedDataLoader systemArtifactsLoader = (HardCodedDataLoader) applicationContext .getBean(componentName); dataLoaders.add(systemArtifactsLoader); } catch (NoSuchBeanDefinitionException e) { log.warn("SystemArtifactsLoder not found."); throw e; } } private void determineInstallationConfiguration() { } private void determineInstallationStatus() { } private PropertyContextOverrides defineInstallationOverrides() { PropertyContextOverrides overrides = new PropertyContextOverrides(); overrides.addProperty(PropertyKeys.APPLICATION_DATABASE_CREATION, PersistentDataInitializationStrategies.dropAndCreate); return overrides; } private List<DataLoader> determineDataLoaders() throws ApplicationException { List<DataLoader> dataLoaders = new ArrayList<DataLoader>(); determinePredefinedDataLoaders(dataLoaders); determineCustomDataLoaders(dataLoaders); return dataLoaders; } private void determinePredefinedDataLoaders(List<DataLoader> dataLoaders) { addPredefinedUsersLoader(dataLoaders); addBusinessDefintionLoader(dataLoaders); addSystemArtifactsLoader(dataLoaders); addPredefinedUsersDataSheetLoader(dataLoaders); } private void determineCustomDataLoaders(List<DataLoader> dataLoaders) throws ApplicationException { List<String> dataLoaderClassNames = applicationContext.getPropertyContext() .getPropertyList(PropertyKeys.DATA_LOADER_CLASSES.getDefaultKey()); Integer dataLoaderIndex = 0; for (Iterator<String> iter = dataLoaderClassNames.iterator(); iter.hasNext();) { String className = (String) iter.next(); String selector = MessageFormat.format(PropertyKeys.DATA_LOADER_CONFIGURATION.getDefaultKey(), new Object[] { dataLoaderIndex.toString() }); HierarchicalConfiguration dataLoaderConfig = applicationContext.getPropertyContext() .getConfigurationAt(selector); DataLoader dataLoader = instantitateDataLoader(className, dataLoaderConfig); dataLoaders.add(dataLoader); dataLoaderIndex++; } } private String determineBusinessDefintionsPaths() { PropertyContext propertyContext = applicationContext.getPropertyContext(); List<String> businessDefinitionPaths = propertyContext .getPropertyList(PropertyKeys.BUSINESS_DEFINITION.getDefaultKey()); if (businessDefinitionPaths.size() == 0) { throw new MissingRequiredConfigurationPropertyException( PropertyKeys.BUSINESS_DEFINITION.getDefaultKey(), configurationDescriptorPath); } String combinedPath = ""; for (String path : businessDefinitionPaths) { combinedPath += path + ";"; } return combinedPath; } private void executeDataLoaders(Action action) throws ApplicationException { for (Iterator<DataLoader> iter = dataLoaders.iterator(); iter.hasNext();) { DataLoader dataLoader = iter.next(); if ((action == Action.install && dataLoader.isResultInPersistentObjects()) || (action == Action.start && !dataLoader.isResultInPersistentObjects())) { dataLoader.setResourceLoader(applicationContext.getResourceLoader()); try { dataLoader.loadData(); } catch (Exception e) { throw new ApplicationInstallationException(applicationName, e); } addEventToHistory(Events.dataload); } } } @SuppressWarnings("unchecked") private DataLoader instantitateDataLoader(String className, HierarchicalConfiguration dataLoaderConfig) throws ApplicationException { DataLoader dataLoader = null; Constructor<DataLoader> dataLoaderConstructor; List<HierarchicalConfiguration> arguments = dataLoaderConfig .configurationsAt(INSTANTIATION_ARGUMENTS_SELECTOR); Class<?>[] parameterTypes = new Class[arguments.size()]; Object[] parameterValues = new Object[arguments.size()]; try { for (int j = 0; j < arguments.size(); j++) { String selectorBase = INSTANTIATION_ARGUMENTS_SELECTOR + PropertyContext.PROPERTY_ARRAY_BEGIN + String.valueOf(j) + PropertyContext.PROPERTY_ARRAY_END; String typeSelector = selectorBase + PropertyContext.ATTRIBUTE_BEGIN + PropertyContext.ATTRIBUTE_SIGNER + PARAMETER_TYPE_ELEMENT_NAME + PropertyContext.ATTRIBUTE_END; String paremeterType = dataLoaderConfig.getString(typeSelector); parameterTypes[j] = Class.forName(paremeterType); //String nameSelector = selectorBase + PropertyContext.ATTRIBUTE_BEGIN + PropertyContext.ATTRIBUTE_SIGNER + PARAMETER_NAME_ELEMENT_NAME + PropertyContext.ATTRIBUTE_END; String parameterValue = dataLoaderConfig.getString(selectorBase); parameterValues[j] = parameterValue; } Class<DataLoader> dataLoaderClass = (Class<DataLoader>) Class.forName(className); dataLoaderConstructor = dataLoaderClass.getConstructor(parameterTypes); dataLoader = (DataLoader) dataLoaderConstructor.newInstance(parameterValues); } catch (SecurityException e) { throw new ApplicationStartException(this, e); } catch (NoSuchMethodException e) { throw new ApplicationStartException(this, e); } catch (IllegalArgumentException e) { throw new ApplicationStartException(this, e); } catch (InstantiationException e) { throw new ApplicationStartException(this, e); } catch (IllegalAccessException e) { throw new ApplicationStartException(this, e); } catch (InvocationTargetException e) { throw new ApplicationStartException(this, e); } catch (ClassNotFoundException e) { throw new ApplicationStartException(this, e); } return dataLoader; } private void persistSystemInstallerUser() { User systemInstaller = UserRequestManager.getInstance().currentUser(); UserRepository userRepository = applicationContext.getRepository(UserRepository.class); userRepository.add(systemInstaller); } private void setUpApplicationContext(Action applicationAction, PropertyContextOverrides overrides) throws ApplicationException { try { if (applicationContext == null) applicationContext = new ProcessPuzzleContext(this, configurationDescriptorPath); if (!applicationContext.isConfigured()) { if (overrides != null) applicationContext.setPropertyContextOverrides(overrides); applicationContext.setUp(applicationAction); } // applicationName = applicationContext.getProperty( PropertyKeys.APPLICATION_NAME.getXPathKey() ); } catch (Exception e) { // applicationName = applicationContext.getProperty( PropertyKeys.APPLICATION_NAME.getXPathKey() ); String message = "Starting " + applicationName + "application failed."; log.error(message, e); applicationContext = null; throw new ApplicationStartException(this, e); } } }