source: trunk/quest-core-events/src/main/java/de/ugoe/cs/quest/eventcore/guimodel/GUIElementFactory.java @ 610

Last change on this file since 610 was 610, checked in by pharms, 12 years ago
  • improved error handling in the case the GUI element type mapping is incomplete
File size: 10.6 KB
Line 
1// Module    : $RCSfile: AbstractDefaultGUIElementFactory.java,v $
2// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 13.05.2012 $
3// Project   : GUIModel
4// Creation  : 2012 by patrick
5// Copyright : Patrick Harms, 2012
6
7package de.ugoe.cs.quest.eventcore.guimodel;
8
9import java.io.File;
10import java.io.FileInputStream;
11import java.io.FileNotFoundException;
12import java.io.IOException;
13import java.io.InputStream;
14import java.lang.reflect.Constructor;
15import java.lang.reflect.InvocationTargetException;
16import java.util.Properties;
17import java.util.logging.Level;
18import java.util.logging.Logger;
19
20/**
21 * TODO comment
22 *
23 * TODO rename class to GUIElementFactory
24 *
25 * @version $Revision: $ $Date: 13.05.2012$
26 * @author 2012, last modified by $Author: patrick$
27 */
28public class GUIElementFactory implements IGUIElementFactory {
29   
30    /** */
31    private static GUIElementFactory instance = new GUIElementFactory();
32
33    /**
34     * TODO: comment
35     *
36     */
37    private GUIElementFactory() {
38    }
39
40    /**
41     * TODO: comment
42     *
43     * @return
44     */
45    public static synchronized GUIElementFactory getInstance() {
46        return instance;
47    }
48
49   
50    /** */
51    private Properties mappingsFromConfiguration;
52
53    /**
54     * TODO: comment
55     *
56     * @param object1
57     * @param object2
58     * @return
59     */
60    protected boolean equals(Object object1, Object object2) {
61        if (object1 == object2) {
62            return true;
63        }
64        else if (object1 != null) {
65            return object1.equals(object2);
66        }
67        else {
68            // object 1 is null but object 2 not --> return false
69            return false;
70        }
71    }
72
73    /**
74     * TODO: comment
75     *
76     * @param parameterTypes
77     * @param parameters
78     * @return
79     * @throws GUIModelConfigurationException
80     */
81    @Override
82    public IGUIElement instantiateGUIElement(IGUIElementSpec specification, IGUIElement parent)
83        throws GUIModelConfigurationException
84    {
85        Properties mappings = getMappingsFromConfiguration();
86        IGUIElement guiElement = null;
87
88        String className = mappings.getProperty(specification.getType());
89        if (className != null) {
90            try {
91                Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
92
93                if (!IGUIElement.class.isAssignableFrom(clazz)) {
94                    Logger.getLogger(this.getClass().getName()).warning
95                        ("configured GUI element representing class " + className +
96                         " is no valid GUIElement " + "derivate.");
97
98                    return null;
99                }
100
101                Constructor<?> constructor = null;
102                Class<?> parentClass = (parent == null) ? null : parent.getClass();
103               
104                // search for a constructor, that perfectly matches the types
105                for (Constructor<?> candidate : clazz.getConstructors()) {
106                    if ((parentClass != null) &&
107                        (candidate.getParameterTypes().length == 2) &&
108                        (candidate.getParameterTypes()[0].equals(specification.getClass())) &&
109                        (candidate.getParameterTypes()[1].equals(parentClass)))
110                    {
111                        constructor = candidate;
112                        break;
113                    }
114                    else if (parentClass == null) {
115                        if ((candidate.getParameterTypes().length >= 1) &&
116                            (candidate.getParameterTypes()[0].equals(specification.getClass())))
117                        {
118                            constructor = candidate;
119                            break;
120                        }
121                    }
122                }
123               
124                if (constructor == null) {
125                    // search for an assignable constructor
126                    for (Constructor<?> candidate : clazz.getConstructors()) {
127                        if ((candidate.getParameterTypes().length == 2) &&
128                            (candidate.getParameterTypes()[0].isInstance(specification)) &&
129                            (candidate.getParameterTypes()[1].isInstance(parent)))
130                        {
131                            constructor = candidate;
132                            break;
133                        }
134                    }
135                   
136                }
137               
138                if (constructor != null) {
139                    guiElement = (IGUIElement) constructor.newInstance(specification, parent);
140                }
141                else {
142                    throw new NoSuchMethodException
143                        ("no constructor with two parameters and assignable parameter types for " +
144                         specification.getClass() + " and " +
145                         (parent != null ? parent.getClass() : "null") + " found in class " +
146                         clazz);
147                }
148
149            }
150            catch (ClassNotFoundException e) {
151                Logger.getLogger(this.getClass().getName()).warning
152                    ("configured GUI element representing class " + className +
153                     " can not be loaded.");
154                throw new GUIModelConfigurationException
155                    ("configured GUI element representing class " + className +
156                     " can not be loaded.", e);
157            }
158            catch (SecurityException e) {
159                Logger.getLogger(this.getClass().getName()).log
160                    (Level.WARNING, "configured GUI element representing class " + className +
161                     " can not be instantiated due to security reasons.", e);
162                throw new GUIModelConfigurationException
163                    ("configured GUI element representing class " + className +
164                     " can not be instantiated due to security reasons.", e);
165            }
166            catch (NoSuchMethodException e) {
167                Logger.getLogger(this.getClass().getName()).warning
168                    ("configured GUI element representing class " + className +
169                     " does not provide an appropriate constructur.");
170                throw new GUIModelConfigurationException
171                    ("configured GUI element representing class " + className +
172                     " does not provide an appropriate constructur.", e);
173            }
174            catch (IllegalArgumentException e) {
175                Logger.getLogger(this.getClass().getName()).warning
176                    ("configured GUI element representing class " + className + " does not " +
177                     "provide an appropriate constructur accepting the provided parameters.");
178                throw new GUIModelConfigurationException
179                    ("configured GUI element representing class " + className + " does not " +
180                     "provide an appropriate constructur accepting the provided parameters.", e);
181            }
182            catch (InstantiationException e) {
183                Logger.getLogger(this.getClass().getName()).log
184                    (Level.WARNING, "configured GUI element representing class " + className +
185                     " can not be instantiated.", e);
186                throw new GUIModelConfigurationException
187                    ("configured GUI element representing class " + className +
188                     " can not be instantiated.", e);
189            }
190            catch (IllegalAccessException e) {
191                Logger.getLogger(this.getClass().getName()).log
192                    (Level.WARNING, "configured GUI element representing class " + className +
193                     " can not be instantiated.", e);
194                throw new GUIModelConfigurationException
195                    ("configured GUI element representing class " + className +
196                     " can not be instantiated.", e);
197            }
198            catch (InvocationTargetException e) {
199                Logger.getLogger(this.getClass().getName()).log
200                    (Level.WARNING, "configured GUI element representing class " + className +
201                     " can not be instantiated.", e);
202                throw new GUIModelConfigurationException
203                    ("configured GUI element representing class " + className +
204                     " can not be instantiated.", e);
205            }
206        }
207       
208        if (guiElement == null ) {
209            Logger.getLogger(this.getClass().getName()).log
210                (Level.WARNING, "no class representing GUI elements of type " +
211                 specification.getType() + " found. Please extends GUI element mapping files.");
212            throw new GUIModelConfigurationException
213                ("no class representing GUI elements of type " + specification.getType() +
214                 " found. Please extends GUI element mapping files");
215        }
216
217        return guiElement;
218    }
219
220    /**
221     * TODO: comment
222     *
223     * @return
224     */
225    private synchronized Properties getMappingsFromConfiguration()
226        throws GUIModelConfigurationException
227    {
228        if (mappingsFromConfiguration != null) {
229            return mappingsFromConfiguration;
230        }
231        else {
232            mappingsFromConfiguration = new Properties();
233           
234            File mappingsFolder = new File("data/guimappings");
235            File[] children = mappingsFolder.listFiles();
236           
237            if (children != null) {
238                for (File mappingsFile : children) {
239                    if (!mappingsFile.isDirectory() &&
240                        mappingsFile.getName().startsWith("guimapping") &&
241                        mappingsFile.getName().endsWith(".txt"))
242                    {
243                        InputStream inStream;
244                        try {
245                            inStream = new FileInputStream(mappingsFile);
246                            mappingsFromConfiguration.load(inStream);
247                            inStream.close();
248                        }
249                        catch (FileNotFoundException e) {
250                            throw new GUIModelConfigurationException
251                                ("could not read mapping configuration file " + mappingsFile, e);
252                        }
253                        catch (IOException e) {
254                            throw new GUIModelConfigurationException
255                                ("could not read mapping configuration file " + mappingsFile, e);
256                        }
257                    }
258                }
259            }
260            else {
261                throw new GUIModelConfigurationException
262                    ("no GUI mappings file provided in folder " + mappingsFolder);
263            }
264
265            return mappingsFromConfiguration;
266        }
267    }
268}
Note: See TracBrowser for help on using the repository browser.