Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
NotationProviderFactory2 |
|
| 3.75;3.75 |
1 | /* $Id: NotationProviderFactory2.java 18852 2010-11-20 19:27:11Z mvw $ | |
2 | ***************************************************************************** | |
3 | * Copyright (c) 2009-2010 Contributors - see below | |
4 | * All rights reserved. This program and the accompanying materials | |
5 | * are made available under the terms of the Eclipse Public License v1.0 | |
6 | * which accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Michiel van der Wulp | |
11 | ***************************************************************************** | |
12 | * | |
13 | * Some portions of this file was previously release using the BSD License: | |
14 | */ | |
15 | ||
16 | // Copyright (c) 2005-2009 The Regents of the University of California. All | |
17 | // Rights Reserved. Permission to use, copy, modify, and distribute this | |
18 | // software and its documentation without fee, and without a written | |
19 | // agreement is hereby granted, provided that the above copyright notice | |
20 | // and this paragraph appear in all copies. This software program and | |
21 | // documentation are copyrighted by The Regents of the University of | |
22 | // California. The software program and documentation are supplied "AS | |
23 | // IS", without any accompanying services from The Regents. The Regents | |
24 | // does not warrant that the operation of the program will be | |
25 | // uninterrupted or error-free. The end-user understands that the program | |
26 | // was developed for research purposes and is advised not to rely | |
27 | // exclusively on the program for any reason. IN NO EVENT SHALL THE | |
28 | // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, | |
29 | // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, | |
30 | // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF | |
31 | // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF | |
32 | // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY | |
33 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
34 | // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE | |
35 | // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF | |
36 | // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, | |
37 | // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
38 | ||
39 | package org.argouml.notation; | |
40 | ||
41 | import java.lang.reflect.Constructor; | |
42 | import java.lang.reflect.InvocationTargetException; | |
43 | import java.util.HashMap; | |
44 | import java.util.Map; | |
45 | ||
46 | import org.apache.log4j.Logger; | |
47 | ||
48 | /** | |
49 | * The NotationProviderFactory2 is a singleton, | |
50 | * since it is the accesspoint for all Figs | |
51 | * to access the textual representation of modelobjects, | |
52 | * and since plugin modules can add extra languages. | |
53 | * | |
54 | * @author Michiel | |
55 | */ | |
56 | public final class NotationProviderFactory2 { | |
57 | ||
58 | 900 | private static final Logger LOG = |
59 | Logger.getLogger(NotationProviderFactory2.class); | |
60 | ||
61 | /** | |
62 | * TYPE_NAME the name of the modelelement, e.g. class, package, state | |
63 | */ | |
64 | public static final int TYPE_NAME = 1; | |
65 | ||
66 | /** | |
67 | * TYPE_TRANSITION the main text shown above the transition. | |
68 | */ | |
69 | public static final int TYPE_TRANSITION = 2; | |
70 | ||
71 | /** | |
72 | * TYPE_STATEBODY the multiline text shown inside the state body. | |
73 | */ | |
74 | public static final int TYPE_STATEBODY = 3; | |
75 | ||
76 | /** | |
77 | * TYPE_ACTIONSTATE the text shown in an actionstate. | |
78 | */ | |
79 | public static final int TYPE_ACTIONSTATE = 4; | |
80 | ||
81 | /** | |
82 | * TYPE_ATTRIBUTE the text shown in a attribute compartment (1 attrib only). | |
83 | */ | |
84 | public static final int TYPE_ATTRIBUTE = 5; | |
85 | ||
86 | /** | |
87 | * TYPE_OPERATION the text shown in a operation compartment (1 oper only). | |
88 | */ | |
89 | public static final int TYPE_OPERATION = 6; | |
90 | ||
91 | /** | |
92 | * TYPE_OBJECT the text shown on an object. | |
93 | */ | |
94 | public static final int TYPE_OBJECT = 7; | |
95 | ||
96 | /** | |
97 | * TYPE_COMPONENTINSTANCE the text shown on a componentInstance. | |
98 | */ | |
99 | public static final int TYPE_COMPONENTINSTANCE = 8; | |
100 | ||
101 | /** | |
102 | * TYPE_NODEINSTANCE the text shown on a componentInstance. | |
103 | */ | |
104 | public static final int TYPE_NODEINSTANCE = 9; | |
105 | ||
106 | /** | |
107 | * TYPE_TYPE_OBJECTFLOWSTATE_TYPE the text shown on a | |
108 | * objectflowstate's type, i.e. its classifier name. | |
109 | */ | |
110 | public static final int TYPE_OBJECTFLOWSTATE_TYPE = 10; | |
111 | ||
112 | /** | |
113 | * TYPE_OBJECTFLOWSTATE_STATE the text shown on a | |
114 | * objectflowstate's state. | |
115 | */ | |
116 | public static final int TYPE_OBJECTFLOWSTATE_STATE = 11; | |
117 | ||
118 | /** | |
119 | * TYPE_CALLSTATE the text shown on a | |
120 | * callstate's state. | |
121 | */ | |
122 | public static final int TYPE_CALLSTATE = 12; | |
123 | ||
124 | /** | |
125 | * TYPE_CLASSIFIERROLE the text shown on a | |
126 | * classifierrole. | |
127 | */ | |
128 | public static final int TYPE_CLASSIFIERROLE = 13; | |
129 | ||
130 | /** | |
131 | * TYPE_MESSAGE the text shown on a Message | |
132 | * in a Collaborations diagram. | |
133 | */ | |
134 | public static final int TYPE_MESSAGE = 14; | |
135 | ||
136 | /** | |
137 | * TYPE_EXTENSION_POINT the text shown on a usecase | |
138 | * representing the extensionpoint. | |
139 | */ | |
140 | public static final int TYPE_EXTENSION_POINT = 15; | |
141 | ||
142 | /** | |
143 | * The text shown at the association end that represents the role. | |
144 | */ | |
145 | public static final int TYPE_ASSOCIATION_END_NAME = 16; | |
146 | ||
147 | /** | |
148 | * The text shown for the association role name. | |
149 | */ | |
150 | public static final int TYPE_ASSOCIATION_ROLE = 17; | |
151 | ||
152 | /** | |
153 | * The text shown for the association role name. | |
154 | */ | |
155 | public static final int TYPE_ASSOCIATION_NAME = 18; | |
156 | ||
157 | /** | |
158 | * The text shown for a multiplicity. | |
159 | */ | |
160 | public static final int TYPE_MULTIPLICITY = 19; | |
161 | ||
162 | /** | |
163 | * The text shown for an enumeration literal. | |
164 | */ | |
165 | public static final int TYPE_ENUMERATION_LITERAL = 20; | |
166 | ||
167 | /** | |
168 | * TYPE_MESSAGE the text shown on a Message | |
169 | * in a Collaborations diagram. | |
170 | */ | |
171 | public static final int TYPE_SD_MESSAGE = 21; | |
172 | ||
173 | /** | |
174 | * defaultLanguage the Notation language used by default, i.e. UML | |
175 | */ | |
176 | private NotationName defaultLanguage; | |
177 | ||
178 | /** | |
179 | * allLanguages is a HashMap with as key the notationName, | |
180 | * and as value a second HashMap. This latter HashMap has as key the "type" | |
181 | * converted to Integer, and as value the provider (NotationProvider). | |
182 | */ | |
183 | private Map<NotationName, Map<Integer, Class>> allLanguages; | |
184 | ||
185 | /** | |
186 | * The instance is the singleton. | |
187 | */ | |
188 | private static NotationProviderFactory2 instance; | |
189 | ||
190 | /** | |
191 | * The constructor. | |
192 | */ | |
193 | private NotationProviderFactory2() { | |
194 | 900 | super(); |
195 | 900 | allLanguages = new HashMap<NotationName, Map<Integer, Class>>(); |
196 | 900 | } |
197 | ||
198 | /** | |
199 | * @return returns the singleton instance | |
200 | */ | |
201 | public static NotationProviderFactory2 getInstance() { | |
202 | 4500 | if (instance == null) { |
203 | 900 | instance = new NotationProviderFactory2(); |
204 | } | |
205 | 4500 | return instance; |
206 | } | |
207 | ||
208 | /** | |
209 | * Get a NotationProvider for the current project. | |
210 | * <p> | |
211 | * If there is any reason for failure, null is returned - no | |
212 | * exception is thrown. | |
213 | * The caller is supposed to deal with receiving null. | |
214 | * <p> | |
215 | * Use this function when you do not want to monitor model | |
216 | * changes which may cause the string to change. | |
217 | * | |
218 | * @param type the provider type | |
219 | * @param object the constructor parameter | |
220 | * @param name the name of the notation language to use | |
221 | * @return the provider, or null if there was any failure | |
222 | */ | |
223 | public NotationProvider getNotationProvider(int type, | |
224 | Object object, NotationName name) { | |
225 | ||
226 | 0 | Class clazz = getNotationProviderClass(type, name); |
227 | 0 | if (clazz != null) { |
228 | try { | |
229 | 0 | Class[] cp = {Object.class}; |
230 | 0 | Constructor constructor = clazz.getConstructor(cp); |
231 | 0 | Object[] params = { |
232 | object, | |
233 | }; | |
234 | 0 | return (NotationProvider) constructor.newInstance(params); |
235 | 0 | } catch (SecurityException e) { |
236 | // TODO: Why aren't we throwing an exception here? | |
237 | // Returning null results in NPE and no explanation why. | |
238 | 0 | LOG.error("Exception caught", e); |
239 | 0 | } catch (NoSuchMethodException e) { |
240 | // TODO: Why aren't we throwing an exception here? | |
241 | // Returning null results in NPE and no explanation why. | |
242 | 0 | LOG.error("Exception caught", e); |
243 | 0 | } catch (IllegalArgumentException e) { |
244 | // TODO: Why aren't we throwing an exception here? | |
245 | // Returning null results in NPE and no explanation why. | |
246 | 0 | LOG.error("Exception caught", e); |
247 | 0 | } catch (InstantiationException e) { |
248 | // TODO: Why aren't we throwing an exception here? | |
249 | // Returning null results in NPE and no explanation why. | |
250 | 0 | LOG.error("Exception caught", e); |
251 | 0 | } catch (IllegalAccessException e) { |
252 | // TODO: Why aren't we throwing an exception here? | |
253 | // Returning null results in NPE and no explanation why. | |
254 | 0 | LOG.error("Exception caught", e); |
255 | 0 | } catch (InvocationTargetException e) { |
256 | // TODO: Why aren't we throwing an exception here? | |
257 | // Returning null results in NPE and no explanation why. | |
258 | 0 | LOG.error("Exception caught", e); |
259 | 0 | } |
260 | } | |
261 | 0 | return null; |
262 | } | |
263 | ||
264 | /** | |
265 | * Get a NotationProvider for the current project. | |
266 | * This also initializes the listeners. | |
267 | * <p> | |
268 | * Use this function when you want to monitor model | |
269 | * changes which may cause the string to change. | |
270 | * | |
271 | * @param type the provider type | |
272 | * @param object the constructor parameter | |
273 | * @param nr the fig that refreshes after the NotationProvider has changed | |
274 | * @param name the name of the notation language to use | |
275 | * @return the provider | |
276 | */ | |
277 | public NotationProvider getNotationProvider(int type, | |
278 | Object object, NotationRenderer nr, | |
279 | NotationName name) { | |
280 | ||
281 | 0 | NotationProvider p = getNotationProvider(type, object, name); |
282 | 0 | p.setRenderer(nr); |
283 | 0 | p.initialiseListener(object); |
284 | 0 | return p; |
285 | } | |
286 | ||
287 | /** | |
288 | * This function looks for the requested notation provider type. | |
289 | * It is guaranteed to deliver:<ul> | |
290 | * <li>the requested type of the requested notation language, | |
291 | * <li>the requested type of the default notation, or | |
292 | * <li><code>null</code>. | |
293 | * </ul> | |
294 | * | |
295 | * @param type the provider type | |
296 | * @param name the context (i.e. the notation name) | |
297 | * @return the provider | |
298 | */ | |
299 | private Class getNotationProviderClass(int type, NotationName name) { | |
300 | 0 | if (allLanguages.containsKey(name)) { |
301 | 0 | Map<Integer, Class> t = allLanguages.get(name); |
302 | 0 | if (t.containsKey(Integer.valueOf(type))) { |
303 | 0 | return t.get(Integer.valueOf(type)); |
304 | } | |
305 | } | |
306 | 0 | Map<Integer, Class> t = allLanguages.get(defaultLanguage); |
307 | 0 | if (t != null && t.containsKey(Integer.valueOf(type))) { |
308 | 0 | return t.get(Integer.valueOf(type)); |
309 | } | |
310 | 0 | return null; |
311 | } | |
312 | ||
313 | /** | |
314 | * @param type the provider type | |
315 | * @param notationName the name of the notation (language) | |
316 | * @param provider the provider | |
317 | */ | |
318 | public void addNotationProvider(int type, | |
319 | NotationName notationName, Class provider) { | |
320 | 23400 | if (allLanguages.containsKey(notationName)) { |
321 | 21600 | Map<Integer, Class> t = allLanguages.get(notationName); |
322 | 21600 | t.put(Integer.valueOf(type), provider); |
323 | 21600 | } else { |
324 | 1800 | Map<Integer, Class> t = new HashMap<Integer, Class>(); |
325 | 1800 | t.put(Integer.valueOf(type), provider); |
326 | 1800 | allLanguages.put(notationName, t); |
327 | } | |
328 | 23400 | } |
329 | ||
330 | /** | |
331 | * @param notationName the UML notation that is to be used as default | |
332 | * if no other is found | |
333 | */ | |
334 | public void setDefaultNotation(NotationName notationName) { | |
335 | 900 | if (allLanguages.containsKey(notationName)) { |
336 | 900 | defaultLanguage = notationName; |
337 | } | |
338 | 900 | } |
339 | ||
340 | /** | |
341 | * We need this to remove modules. | |
342 | * | |
343 | * @param notationName the notation to be removed | |
344 | * @return true if the notation was removed | |
345 | */ | |
346 | public boolean removeNotation(NotationName notationName) { | |
347 | 0 | if (defaultLanguage == notationName) { |
348 | 0 | return false; |
349 | } | |
350 | 0 | if (allLanguages.containsKey(notationName)) { |
351 | 0 | return allLanguages.remove(notationName) != null |
352 | && Notation.removeNotation(notationName); | |
353 | } | |
354 | 0 | return false; |
355 | } | |
356 | ||
357 | } |