001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.convert;
025:
026: import jacareto.conceptualmodel.ConceptualModelElement;
027: import jacareto.system.Environment;
028: import jacareto.toolkit.EnhancedHashtable;
029: import jacareto.toolkit.PriorityList;
030:
031: import java.lang.reflect.Constructor;
032: import java.lang.reflect.InvocationTargetException;
033:
034: import java.util.Enumeration;
035: import java.util.Iterator;
036:
037: /**
038: * This converter selects a registered converter for a given object.
039: *
040: * @author <a href="mailto:markus.bois@web.de">Markus Bois</a>
041: * @version 1.02
042: */
043: public class SelectionConceptualModelConverter extends
044: ConceptualModelConverter {
045: /** Load the converters from the customization at the beginning. */
046: public static final int INIT_CUSTOM = 0;
047:
048: /** There should no converters be added at the beginning. */
049: public static final int INIT_EMPTY = 1;
050:
051: /** List of all registered converters. */
052: private PriorityList converters;
053:
054: /**
055: * Creates a new selection converter.
056: *
057: * @param env the environment
058: * @param customizationKey the key of the customization map for this selection converter
059: * @param init {@link #INIT_CUSTOM} or {@link #INIT_EMPTY}
060: */
061: public SelectionConceptualModelConverter(Environment env,
062: String customizationKey, int init) {
063: super (env);
064: converters = new PriorityList();
065:
066: if (init == INIT_CUSTOM) {
067: loadConverters(customizationKey);
068: }
069: }
070:
071: /**
072: * Registers a Converter with the specified priority. A greater value of priority symbolizes a
073: * higher priority.
074: *
075: * @param converter the converter to add
076: * @param priority the priority
077: */
078: public void addConverter(
079: RecursiveConceptualModelConverter converter, int priority) {
080: if (priority >= 0) {
081: converters.add(converter, priority);
082: } else {
083: converters.add(converter);
084: }
085: }
086:
087: /**
088: * Registers a Converter with the lowest priority.
089: *
090: * @param converter the converter to add
091: */
092: public void addConverter(RecursiveConceptualModelConverter converter) {
093: addConverter(converter, -1);
094: }
095:
096: /**
097: * Returns an iterator on all registered converters, sorted by priority. The converter with the
098: * highest priority comes first.
099: *
100: * @return the iterator;
101: */
102: public Iterator convertersIterator() {
103: return converters.iterator();
104: }
105:
106: /**
107: * Returns whether this converter is able to transform the specified conceptual-model element
108: * to an other representation. A selection converter handles a element if a registered
109: * converter handles it.
110: *
111: * @param element the conceptual-model element
112: *
113: * @return <code>true</code> if this converter is responsible for this cocneptual-model
114: * element; otherwise <code>false</code>.
115: */
116: public boolean handlesElement(ConceptualModelElement element) {
117: boolean result = false;
118: Iterator it = convertersIterator();
119:
120: while (it.hasNext() && !result) {
121: RecursiveConceptualModelConverter tmp = (RecursiveConceptualModelConverter) it
122: .next();
123: result |= tmp.handlesElement(element);
124: }
125:
126: return result;
127: }
128:
129: /**
130: * Converts the specified element to an other representation. The precondition for this method
131: * is that the converter handles the given conceptual-model element.
132: *
133: * @param element the conceptual-model element to convert
134: *
135: * @return the other representation
136: */
137: public Object convertElement(ConceptualModelElement element) {
138: return getConverterForElement(element).convertElement(element);
139: }
140:
141: /**
142: * Returns whether this converter is able to transform the specified other representation to a
143: * conceptual-model element. A selection converter handles a representation if a registered
144: * converter handles it.
145: *
146: * @param other the other representation
147: *
148: * @return <code>true</code> if this converter is responsible for this other representation;
149: * otherwise <code>false</code>.
150: */
151: public boolean handlesOther(Object other) {
152: boolean result = false;
153: Iterator it = convertersIterator();
154:
155: while (it.hasNext() && !result) {
156: RecursiveConceptualModelConverter tmp = (RecursiveConceptualModelConverter) it
157: .next();
158: result |= tmp.handlesOther(other);
159: }
160:
161: return result;
162: }
163:
164: /**
165: * Converts the specified other representation to a conceptual-model element. The precondition
166: * for this method is that the converter handles the given other representation.
167: *
168: * @param other the other representation to convert
169: *
170: * @return the conceptual-model element
171: */
172: public ConceptualModelElement convertOther(Object other) {
173: return getConverterForOther(other).convertOther(other);
174: }
175:
176: /**
177: * Returns the first converter which feels responsible for the given element. If no converter
178: * is responsible, <code>null</code> will be returned
179: *
180: * @param element the conceptual-model element.
181: *
182: * @return the first converter which feels responsible, or <code>null</code> if no converter is
183: * responsible.
184: */
185: protected RecursiveConceptualModelConverter getConverterForElement(
186: ConceptualModelElement element) {
187: RecursiveConceptualModelConverter converter;
188: Iterator i = convertersIterator();
189:
190: while (i.hasNext()) {
191: converter = (RecursiveConceptualModelConverter) i.next();
192:
193: if (converter.handlesElement(element)) {
194: return converter;
195: }
196: }
197:
198: return null;
199: }
200:
201: /**
202: * Returns the first converter which feels responsible for the given other representation. If
203: * no converter is responsible, <code>null</code> will be returned
204: *
205: * @param other the other representation
206: *
207: * @return the first converter which feels responsible, or <code>null</code> if no converter is
208: * responsible.
209: */
210: protected RecursiveConceptualModelConverter getConverterForOther(
211: Object other) {
212: if (other != null) {
213: RecursiveConceptualModelConverter converter;
214: Iterator i = convertersIterator();
215:
216: while (i.hasNext()) {
217: converter = (RecursiveConceptualModelConverter) i
218: .next();
219:
220: if (converter.handlesOther(other)) {
221: return converter;
222: }
223: }
224: }
225:
226: return null;
227: }
228:
229: /**
230: * Loads the specific converters from the {@link jacareto.system.Customization} instance of the
231: * {@link jacareto.system.Environment} object.
232: *
233: * @param customizationKey the key of the customization element which is the map of the
234: * converters to the priorities
235: */
236: protected void loadConverters(String customizationKey) {
237: try {
238: // some reflection instances
239: Class converterClass = Class
240: .forName("jacareto.convert.RecursiveConceptualModelConverter");
241: Class[] parameterTypes = new Class[2];
242: parameterTypes[0] = Class
243: .forName("jacareto.system.Environment");
244: parameterTypes[1] = Class
245: .forName("jacareto.convert.SelectionConceptualModelConverter");
246:
247: Object[] parameters = new Object[2];
248: parameters[0] = env;
249: parameters[1] = this ;
250:
251: // load the map of converters
252: EnhancedHashtable convertersMap = getCustomization()
253: .getMap(customizationKey, new EnhancedHashtable());
254: Enumeration enumeration = convertersMap.keys();
255:
256: while (enumeration.hasMoreElements()) {
257: try {
258: String converterClassName = (String) enumeration
259: .nextElement();
260: Class concreteConverterClass = Class
261: .forName(converterClassName);
262: Constructor converterConstructor = concreteConverterClass
263: .getConstructor(parameterTypes);
264:
265: if (converterClass
266: .isAssignableFrom(concreteConverterClass)) {
267: try {
268: logger
269: .debug(language
270: .getString("Convert.SelectionConverter.Msg.Loading")
271: + " " + converterClassName);
272: addConverter((RecursiveConceptualModelConverter) converterConstructor
273: .newInstance(parameters));
274: } catch (InstantiationException inst) {
275: logger
276: .error(
277: language
278: .getString("Convert.SelectionConverter.Error.Construction"),
279: inst);
280: } catch (IllegalAccessException ill) {
281: logger
282: .error(
283: language
284: .getString("Convert.SelectionConverter.Error.Construction"),
285: ill);
286: } catch (IllegalArgumentException ila) {
287: logger
288: .error(
289: language
290: .getString("Convert.SelectionConverter.Error.Construction"),
291: ila);
292: } catch (InvocationTargetException inv) {
293: logger
294: .error(
295: language
296: .getString("Convert.SelectionConverter.Error.Construction"),
297: inv);
298: }
299: } else {
300: logger
301: .warn(language
302: .getString("Convert.SelectionConverter.Msg.NotSubclass")
303: + ": " + converterClassName);
304: }
305: } catch (ClassNotFoundException c) {
306: logger
307: .error(
308: language
309: .getString("Convert.SelectionConverter.Error.MissingClass"),
310: c);
311: } catch (NoSuchMethodException n) {
312: logger
313: .error(
314: language
315: .getString("Convert.SelectionConverter.Error.MissingConstructor"),
316: n);
317: }
318: }
319: } catch (ClassNotFoundException c) {
320: logger
321: .error(
322: language
323: .getString("Convert.SelectionConverter.Error.MissingClass"),
324: c);
325: }
326: }
327: }
|