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

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