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.interactionmodel.InteractionModelElement;
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:cspannagel@web.de">Christian Spannagel</a>
041: * @version 1.02
042: */
043: public class SelectionInteractionModelConverter extends
044: InteractionModelConverter {
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 SelectionInteractionModelConverter(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: RecursiveInteractionModelConverter 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(
093: RecursiveInteractionModelConverter converter) {
094: addConverter(converter, -1);
095: }
096:
097: /**
098: * Returns an iterator on all registered converters, sorted by priority. The converter with the
099: * highest priority comes first.
100: *
101: * @return the iterator;
102: */
103: public Iterator convertersIterator() {
104: return converters.iterator();
105: }
106:
107: /**
108: * Returns whether this converter is able to transform the specified interaction-model element
109: * to an other representation. A selection converter handles a element if a registered
110: * converter handles it.
111: *
112: * @param element the interaction-model element
113: *
114: * @return <code>true</code> if this converter is responsible for this interaction-model
115: * element; otherwise <code>false</code>.
116: */
117: public boolean handlesElement(InteractionModelElement element) {
118: boolean result = false;
119: Iterator it = convertersIterator();
120:
121: while (it.hasNext() && !result) {
122: RecursiveInteractionModelConverter tmp = (RecursiveInteractionModelConverter) it
123: .next();
124: result |= tmp.handlesElement(element);
125: }
126:
127: return result;
128: }
129:
130: /**
131: * Converts the specified element to an other representation. The precondition for this method
132: * is that the converter handles the given interaction-model element.
133: *
134: * @param element the interaction-model element to convert
135: *
136: * @return the other representation
137: */
138: public Object convertElement(InteractionModelElement element) {
139: return getConverterForElement(element).convertElement(element);
140: }
141:
142: /**
143: * Returns whether this converter is able to transform the specified other representation to a
144: * interaction-model element. A selection converter handles a representation if a registered
145: * converter handles it.
146: *
147: * @param other the other representation
148: *
149: * @return <code>true</code> if this converter is responsible for this other representation;
150: * otherwise <code>false</code>.
151: */
152: public boolean handlesOther(Object other) {
153: boolean result = false;
154: Iterator it = convertersIterator();
155:
156: while (it.hasNext() && !result) {
157: RecursiveInteractionModelConverter tmp = (RecursiveInteractionModelConverter) it
158: .next();
159: result |= tmp.handlesOther(other);
160: }
161:
162: return result;
163: }
164:
165: /**
166: * Converts the specified other representation to a interaction-model element. The precondition
167: * for this method is that the converter handles the given other representation.
168: *
169: * @param other the other representation to convert
170: *
171: * @return the interaction-model element
172: */
173: public InteractionModelElement convertOther(Object other) {
174: return getConverterForOther(other).convertOther(other);
175: }
176:
177: /**
178: * Returns the first converter which feels responsible for the given element. If no converter
179: * is responsible, <code>null</code> will be returned
180: *
181: * @param element the interaction-model element.
182: *
183: * @return the first converter which feels responsible, or <code>null</code> if no converter is
184: * responsible.
185: */
186: protected RecursiveInteractionModelConverter getConverterForElement(
187: InteractionModelElement element) {
188: RecursiveInteractionModelConverter converter;
189: Iterator i = convertersIterator();
190:
191: while (i.hasNext()) {
192: converter = (RecursiveInteractionModelConverter) i.next();
193:
194: if (converter.handlesElement(element)) {
195: return converter;
196: }
197: }
198:
199: return null;
200: }
201:
202: /**
203: * Returns the first converter which feels responsible for the given other representation. If
204: * no converter is responsible, <code>null</code> will be returned
205: *
206: * @param other the other representation
207: *
208: * @return the first converter which feels responsible, or <code>null</code> if no converter is
209: * responsible.
210: */
211: protected RecursiveInteractionModelConverter getConverterForOther(
212: Object other) {
213: if (other != null) {
214: RecursiveInteractionModelConverter converter;
215: Iterator i = convertersIterator();
216:
217: while (i.hasNext()) {
218: converter = (RecursiveInteractionModelConverter) i
219: .next();
220:
221: if (converter.handlesOther(other)) {
222: return converter;
223: }
224: }
225: }
226:
227: return null;
228: }
229:
230: /**
231: * Loads the specific converters from the {@link jacareto.system.Customization} instance of the
232: * {@link jacareto.system.Environment} object.
233: *
234: * @param customizationKey the key of the customization element which is the map of the
235: * converters to the priorities
236: */
237: protected void loadConverters(String customizationKey) {
238: try {
239: // some reflection instances
240: Class converterClass = Class
241: .forName("jacareto.convert.RecursiveInteractionModelConverter");
242: Class[] parameterTypes = new Class[2];
243: parameterTypes[0] = Class
244: .forName("jacareto.system.Environment");
245: parameterTypes[1] = Class
246: .forName("jacareto.convert.SelectionInteractionModelConverter");
247:
248: Object[] parameters = new Object[2];
249: parameters[0] = env;
250: parameters[1] = this ;
251:
252: // load the map of converters
253: EnhancedHashtable convertersMap = getCustomization()
254: .getMap(customizationKey, new EnhancedHashtable());
255: Enumeration enumeration = convertersMap.keys();
256:
257: while (enumeration.hasMoreElements()) {
258: try {
259: String converterClassName = (String) enumeration
260: .nextElement();
261: Class concreteConverterClass = Class
262: .forName(converterClassName);
263: Constructor converterConstructor = concreteConverterClass
264: .getConstructor(parameterTypes);
265:
266: if (converterClass
267: .isAssignableFrom(concreteConverterClass)) {
268: try {
269: logger
270: .debug(language
271: .getString("Convert.SelectionConverter.Msg.Loading")
272: + " " + converterClassName);
273: addConverter((RecursiveInteractionModelConverter) converterConstructor
274: .newInstance(parameters));
275: } catch (InstantiationException inst) {
276: logger
277: .error(
278: language
279: .getString("Convert.SelectionConverter.Error.Construction"),
280: inst);
281: } catch (IllegalAccessException ill) {
282: logger
283: .error(
284: language
285: .getString("Convert.SelectionConverter.Error.Construction"),
286: ill);
287: } catch (IllegalArgumentException ila) {
288: logger
289: .error(
290: language
291: .getString("Convert.SelectionConverter.Error.Construction"),
292: ila);
293: } catch (InvocationTargetException inv) {
294: logger
295: .error(
296: language
297: .getString("Convert.SelectionConverter.Error.Construction"),
298: inv);
299: }
300: } else {
301: logger
302: .warn(language
303: .getString("Convert.SelectionConverter.Msg.NotSubclass")
304: + ": " + converterClassName);
305: }
306: } catch (ClassNotFoundException c) {
307: logger
308: .error(
309: language
310: .getString("Convert.SelectionConverter.Error.MissingClass"),
311: c);
312: } catch (NoSuchMethodException n) {
313: logger
314: .error(
315: language
316: .getString("Convert.SelectionConverter.Error.MissingConstructor"),
317: n);
318: }
319: }
320: } catch (ClassNotFoundException c) {
321: logger
322: .error(
323: language
324: .getString("Convert.SelectionConverter.Error.MissingClass"),
325: c);
326: }
327: }
328: }
|