// Module : $RCSfile: AbstractDefaultGUIElementFactory.java,v $ // Version : $Revision: 0.0 $ $Author: patrick $ $Date: 13.05.2012 $ // Project : GUIModel // Creation : 2012 by patrick // Copyright : Patrick Harms, 2012 package de.ugoe.cs.quest.eventcore.guimodel; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * TODO comment * * TODO rename class to GUIElementFactory * * @version $Revision: $ $Date: 13.05.2012$ * @author 2012, last modified by $Author: patrick$ */ public class GUIElementFactory implements IGUIElementFactory { /** */ private static GUIElementFactory instance = new GUIElementFactory(); /** * TODO: comment * */ private GUIElementFactory() { } /** * TODO: comment * * @return */ public static synchronized GUIElementFactory getInstance() { return instance; } /** */ private Properties mappingsFromConfiguration; /** * TODO: comment * * @param object1 * @param object2 * @return */ protected boolean equals(Object object1, Object object2) { if (object1 == object2) { return true; } else if (object1 != null) { return object1.equals(object2); } else { // object 1 is null but object 2 not --> return false return false; } } /** * TODO: comment * * @param parameterTypes * @param parameters * @return * @throws GUIModelConfigurationException */ @Override public IGUIElement instantiateGUIElement(IGUIElementSpec specification, IGUIElement parent) throws GUIModelConfigurationException { Properties mappings = getMappingsFromConfiguration(); IGUIElement guiElement = null; String className = mappings.getProperty(specification.getType()); if (className != null) { try { Class clazz = this.getClass().getClassLoader().loadClass(className); if (!IGUIElement.class.isAssignableFrom(clazz)) { Logger.getLogger(this.getClass().getName()).warning ("configured GUI element representing class " + className + " is no valid GUIElement " + "derivate."); return null; } Constructor constructor = null; Class parentClass = (parent == null) ? null : parent.getClass(); // search for a constructor, that perfectly matches the types for (Constructor candidate : clazz.getConstructors()) { if ((parentClass != null) && (candidate.getParameterTypes().length == 2) && (candidate.getParameterTypes()[0].equals(specification.getClass())) && (candidate.getParameterTypes()[1].equals(parentClass))) { constructor = candidate; break; } else if (parentClass == null) { if ((candidate.getParameterTypes().length >= 1) && (candidate.getParameterTypes()[0].equals(specification.getClass()))) { constructor = candidate; break; } } } if (constructor == null) { // search for an assignable constructor for (Constructor candidate : clazz.getConstructors()) { if ((candidate.getParameterTypes().length == 2) && (candidate.getParameterTypes()[0].isInstance(specification)) && (candidate.getParameterTypes()[1].isInstance(parent))) { constructor = candidate; break; } } } if (constructor != null) { guiElement = (IGUIElement) constructor.newInstance(specification, parent); } else { throw new NoSuchMethodException ("no constructor with two parameters and assignable parameter types for " + specification.getClass() + " and " + (parent != null ? parent.getClass() : "null") + " found in class " + clazz); } } catch (ClassNotFoundException e) { Logger.getLogger(this.getClass().getName()).warning ("configured GUI element representing class " + className + " can not be loaded."); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " can not be loaded.", e); } catch (SecurityException e) { Logger.getLogger(this.getClass().getName()).log (Level.WARNING, "configured GUI element representing class " + className + " can not be instantiated due to security reasons.", e); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " can not be instantiated due to security reasons.", e); } catch (NoSuchMethodException e) { Logger.getLogger(this.getClass().getName()).warning ("configured GUI element representing class " + className + " does not provide an appropriate constructur."); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " does not provide an appropriate constructur.", e); } catch (IllegalArgumentException e) { Logger.getLogger(this.getClass().getName()).warning ("configured GUI element representing class " + className + " does not " + "provide an appropriate constructur accepting the provided parameters."); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " does not " + "provide an appropriate constructur accepting the provided parameters.", e); } catch (InstantiationException e) { Logger.getLogger(this.getClass().getName()).log (Level.WARNING, "configured GUI element representing class " + className + " can not be instantiated.", e); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " can not be instantiated.", e); } catch (IllegalAccessException e) { Logger.getLogger(this.getClass().getName()).log (Level.WARNING, "configured GUI element representing class " + className + " can not be instantiated.", e); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " can not be instantiated.", e); } catch (InvocationTargetException e) { Logger.getLogger(this.getClass().getName()).log (Level.WARNING, "configured GUI element representing class " + className + " can not be instantiated.", e); throw new GUIModelConfigurationException ("configured GUI element representing class " + className + " can not be instantiated.", e); } } if (guiElement == null ) { Logger.getLogger(this.getClass().getName()).log (Level.WARNING, "no class representing GUI elements of type " + specification.getType() + " found. Please extends GUI element mapping files."); throw new GUIModelConfigurationException ("no class representing GUI elements of type " + specification.getType() + " found. Please extends GUI element mapping files"); } return guiElement; } /** * TODO: comment * * @return */ private synchronized Properties getMappingsFromConfiguration() throws GUIModelConfigurationException { if (mappingsFromConfiguration != null) { return mappingsFromConfiguration; } else { mappingsFromConfiguration = new Properties(); File mappingsFolder = new File("data/guimappings"); File[] children = mappingsFolder.listFiles(); if (children != null) { for (File mappingsFile : children) { if (!mappingsFile.isDirectory() && mappingsFile.getName().startsWith("guimapping") && mappingsFile.getName().endsWith(".txt")) { InputStream inStream; try { inStream = new FileInputStream(mappingsFile); mappingsFromConfiguration.load(inStream); inStream.close(); } catch (FileNotFoundException e) { throw new GUIModelConfigurationException ("could not read mapping configuration file " + mappingsFile, e); } catch (IOException e) { throw new GUIModelConfigurationException ("could not read mapping configuration file " + mappingsFile, e); } } } } else { throw new GUIModelConfigurationException ("no GUI mappings file provided in folder " + mappingsFolder); } return mappingsFromConfiguration; } } }