View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package net.sf.magicproject.xml;
20  
21  import java.io.IOException;
22  import java.io.OutputStream;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  import net.sf.magicproject.clickable.ability.Optimization;
29  import net.sf.magicproject.clickable.ability.Priority;
30  import net.sf.magicproject.expression.intlist.ListType;
31  import net.sf.magicproject.modifier.ModifierType;
32  import net.sf.magicproject.operation.IdOperations;
33  import net.sf.magicproject.test.TestOn;
34  import net.sf.magicproject.token.AbstractValue;
35  import net.sf.magicproject.token.IdCardColors;
36  import net.sf.magicproject.token.IdConst;
37  import net.sf.magicproject.token.IdMessageBox;
38  import net.sf.magicproject.token.IdPositions;
39  import net.sf.magicproject.token.IdTargets;
40  import net.sf.magicproject.token.IdTokens;
41  import net.sf.magicproject.token.IdZones;
42  import net.sf.magicproject.token.Register;
43  import net.sf.magicproject.tools.MToolKit;
44  import net.sf.magicproject.xml.XmlParser.Node;
45  
46  import org.apache.commons.lang.StringUtils;
47  
48  /***
49   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
50   */
51  public final class XmlTools {
52  
53  	private XmlTools() {
54  		super();
55  	}
56  
57  	private static Map<String, Integer> registerIndexName = new HashMap<String, Integer>();
58  
59  	private static Map<String, Integer> operation = new HashMap<String, Integer>();
60  
61  	private static Map<String, Integer> targetMode = new HashMap<String, Integer>();
62  
63  	private static Map<String, Integer> position = new HashMap<String, Integer>();
64  
65  	/***
66  	 * The available zones.
67  	 * 
68  	 * @see net.sf.magicproject.xml.tbs.Tbs#buildMdb(Node, OutputStream)
69  	 */
70  	public static Map<String, Integer> zones = new HashMap<String, Integer>();
71  
72  	private static Map<String, Integer> definedValuesName = new HashMap<String, Integer>();
73  
74  	private static Map<String, Integer> cardColorsName = new HashMap<String, Integer>();
75  
76  	/***
77  	 * If there is neither attribute neither node with the given name, '-1' is
78  	 * witten instead of throwing an exception.
79  	 * 
80  	 * @param node
81  	 *          the parent node.
82  	 * @param attribute
83  	 *          the attribute/node name to write.
84  	 * @param out
85  	 *          the outputstream.
86  	 * @throws IOException
87  	 *           error while writting.
88  	 */
89  	public static void tryWriteExpression(XmlParser.Node node, String attribute,
90  			OutputStream out) throws IOException {
91  		if (node.getAttribute(attribute) == null && node.get(attribute) == null) {
92  			// no such attribute --> '-1', working on the current list
93  			XmlTools.writeConstant(out, -1);
94  		} else if ("-1".equals(node.getAttribute(attribute))) {
95  			// last index --> ALL, working the last saved list
96  			XmlTools.writeConstant(out, IdConst.ALL);
97  		} else {
98  			// last index --> ALL, working an indexed saved list
99  			XmlTools.writeAttrOptions(node, attribute, out);
100 		}
101 	}
102 
103 	/***
104 	 * Fill the referenced HashMaps
105 	 */
106 	public static void initHashMaps() {
107 		clean();
108 		for (int i = IdTokens.REGISTER_INDEX_NAMES.length; i-- > 0;) {
109 			registerIndexName.put(IdTokens.REGISTER_INDEX_NAMES[i],
110 					IdTokens.REGISTER_INDEX_VALUES[i]);
111 		}
112 		for (int i = IdOperations.OPERATION_NAMES.length; i-- > 0;) {
113 			operation.put(IdOperations.OPERATION_NAMES[i],
114 					IdOperations.OPERATION_VALUES[i]);
115 		}
116 		for (int i = IdTargets.MODE_NAMES.length; i-- > 0;) {
117 			targetMode.put(IdTargets.MODE_NAMES[i], IdTargets.MODE_VALUES[i]);
118 		}
119 		for (int i = IdPositions.POSITION_NAMES.length; i-- > 0;) {
120 			position.put(IdPositions.POSITION_NAMES[i],
121 					IdPositions.POSITION_VALUES[i]);
122 		}
123 		for (int i = IdZones.ZONE_NAMES.length; i-- > 0;) {
124 			zones.put(IdZones.ZONE_NAMES[i], IdZones.ZONE_VALUES[i]);
125 		}
126 		for (int i = IdConst.VALUES_NAME.length; i-- > 0;) {
127 			definedValuesName.put(IdConst.VALUES_NAME[i], IdConst.VALUES[i]);
128 		}
129 		for (int i = IdCardColors.CARD_COLOR_NAMES.length; i-- > 1;) {
130 			cardColorsName.put(IdCardColors.CARD_COLOR_NAMES[i],
131 					IdCardColors.CARD_COLOR_VALUES[i]);
132 		}
133 	}
134 
135 	/***
136 	 * Clean tables.
137 	 */
138 	public static void clean() {
139 		registerIndexName.clear();
140 		operation.clear();
141 		targetMode.clear();
142 		position.clear();
143 		zones.clear();
144 		definedValuesName.clear();
145 		cardColorsName.clear();
146 		aliasMap = null;
147 		XmlTest.clean();
148 		XmlAction.clean();
149 		XmlExpression.clean();
150 		XmlTbs.clean();
151 		XmlModifier.clean();
152 	}
153 
154 	/***
155 	 * Write the TestOn instance corresponding to the given XSD attribute name.
156 	 * 
157 	 * @param out
158 	 *          the stream ths enum would be written.
159 	 * @param xsdName
160 	 *          the Xsd name of this TestOn.
161 	 * @throws IOException
162 	 *           error while writting.
163 	 */
164 	public static void writeTestOn(OutputStream out, String xsdName)
165 			throws IOException {
166 		if (xsdName != null) {
167 			try {
168 				TestOn.serialize(out, xsdName);
169 			} catch (IllegalArgumentException e) {
170 				XmlConfiguration.error++;
171 				System.out.println("\t>> " + e.getMessage());
172 				TestOn.THIS.serialize(out);
173 			}
174 		} else if (defaultOnMeTag)
175 			TestOn.THIS.serialize(out);
176 		else
177 			TestOn.TESTED.serialize(out);
178 	}
179 
180 	/***
181 	 * @param attribute
182 	 *          the layer name.
183 	 * @return the layer id.
184 	 */
185 	public static int getModifierLayer(String attribute) {
186 		if (attribute == null || "normal".equals(attribute)) {
187 			return ModifierType.NORMAL_LAYER;
188 		}
189 		if ("internal".equals(attribute)) {
190 			return ModifierType.INTERNAL_LAYER;
191 		}
192 		return ModifierType.GLOBAL_LAYER;
193 	}
194 
195 	/***
196 	 * @param attribute
197 	 *          the optimization name.
198 	 * @return the optimization id.
199 	 */
200 	public static Optimization getOptimization(String attribute) {
201 		if (attribute == null)
202 			return net.sf.magicproject.clickable.ability.Optimization.none;
203 		return Optimization.valueOf(attribute);
204 	}
205 
206 	/***
207 	 * Return the operation code
208 	 * 
209 	 * @param operation
210 	 *          the alias
211 	 * @return the operation code
212 	 * @see net.sf.magicproject.action.ModifyRegister
213 	 */
214 	public static int getOperation(String operation) {
215 		if (operation == null) {
216 			return IdOperations.ANY;
217 		}
218 		Object obj = XmlTools.operation.get(operation);
219 		if (obj != null) {
220 			return ((Integer) obj).intValue();
221 		}
222 		XmlConfiguration.error++;
223 		System.out.println("\t>> Unknown operation : '" + operation + "'");
224 		return 0;
225 	}
226 
227 	/***
228 	 * Return the resolution code
229 	 * 
230 	 * @param resolution
231 	 *          the alias
232 	 * @return the resolution code
233 	 */
234 	public static Priority getPriority(String resolution) {
235 		if (resolution == null)
236 			return net.sf.magicproject.clickable.ability.Priority.normal;
237 		return net.sf.magicproject.clickable.ability.Priority.valueOf(resolution);
238 	}
239 
240 	/***
241 	 * Return the corresponding code to the specified target mode.
242 	 * 
243 	 * @param modeAlias
244 	 *          the alias of mode
245 	 * @return the corresponding code to the specified target mode.
246 	 * @see IdTargets#MODE_NAMES
247 	 */
248 	public static int getTargetMode(String modeAlias) {
249 		if (modeAlias == null) {
250 			return IdTargets.CHOOSE;
251 		}
252 		Object obj = XmlTools.targetMode.get(modeAlias);
253 		if (obj != null) {
254 			return ((Integer) obj).intValue();
255 		}
256 		XmlConfiguration.error++;
257 		System.out.println("\t>> Unknown target mode : '" + modeAlias + "'");
258 		return 0;
259 	}
260 
261 	/***
262 	 * Return the corresponding code to the specified position name.
263 	 * 
264 	 * @param positionAlias
265 	 *          the alias of place
266 	 * @return the corresponding code to the specified position name.
267 	 * @see IdPositions#POSITION_NAMES
268 	 */
269 	public static Integer getPosition(String positionAlias) {
270 		if (positionAlias == null) {
271 			return IdPositions.ON_THE_TOP;
272 		}
273 		return XmlTools.position.get(positionAlias);
274 	}
275 
276 	/***
277 	 * Return the corresponding code to the specified zone name.
278 	 * 
279 	 * @param zoneAlias
280 	 *          the alias of place
281 	 * @return the corresponding code to the specified zone name.
282 	 * @see IdZones#ZONE_NAMES
283 	 */
284 	public static int getZone(String zoneAlias) {
285 		Object obj = XmlTools.zones.get(zoneAlias);
286 		if (obj != null) {
287 			return ((Integer) obj).intValue();
288 		}
289 		XmlConfiguration.error++;
290 		System.out.println("\t>> Unknown zone : '" + zoneAlias + "'");
291 		return 0;
292 	}
293 
294 	/***
295 	 * Return the corresponding codeto the specified string register index.
296 	 * 
297 	 * @param alias
298 	 *          the alias of value in it's string form
299 	 * @return the corresponding code to the specified string register index.
300 	 */
301 	public static int getValue(String alias) {
302 		Integer value = getIntPriv(alias);
303 		if (value == null) {
304 			Integer obj = XmlTools.definedValuesName.get(alias);
305 			if (obj != null) {
306 				return obj.intValue();
307 			}
308 			obj = XmlTools.registerIndexName.get(alias);
309 			if (obj != null) {
310 				return obj.intValue();
311 			}
312 			// Thread.dumpStack();
313 			XmlConfiguration.error++;
314 			System.out.println("\t>> Unknown alias : '" + alias + "'");
315 			return 0;
316 		}
317 		return value;
318 	}
319 
320 	/***
321 	 * Return the corresponding code to the specified alias.
322 	 * 
323 	 * @param alias
324 	 *          the alias of value in it's string form
325 	 * @return the corresponding code to the specified alias.
326 	 */
327 	private static Integer getIntPriv(String alias) {
328 		if (alias == null) {
329 			XmlConfiguration.error++;
330 			System.out.println("\t>> Null register/index.");
331 			new RuntimeException().printStackTrace(System.out);
332 			return 0;
333 		}
334 
335 		if (alias.length() > 0) {
336 			switch (alias.charAt(0)) {
337 			case '-':
338 				final int valueNeg = MToolKit.parseInt(alias);
339 				if (valueNeg == Integer.MIN_VALUE) {
340 					// alias not found
341 					return null;
342 				}
343 				return getNegativeConstant(valueNeg);
344 			case '1':
345 			case '2':
346 			case '3':
347 			case '4':
348 			case '5':
349 			case '6':
350 			case '7':
351 			case '8':
352 			case '9':
353 			case '0':
354 				final int value = MToolKit.parseInt(alias);
355 				if (value == Integer.MIN_VALUE) {
356 					// alias not found
357 					return null;
358 				}
359 				return value;
360 			default:
361 				// not managed number
362 			}
363 		}
364 		// it's an alias
365 		final Integer value = aliasMap.get(alias);
366 		if (value != null)
367 			return getNegativeConstant(value);
368 		return XmlTools.registerIndexName.get(alias);
369 	}
370 
371 	private static int getNegativeConstant(int value) {
372 		if (value < 0) {
373 			if (value < -127) {
374 				throw new InternalError("Negative number cannot exceed -127 : " + value);
375 			}
376 			return IdConst.NEGATIVE_NUMBER_MASK | -value;
377 		}
378 		return value;
379 	}
380 
381 	/***
382 	 * Return the corresponding code to the specified alias.
383 	 * 
384 	 * @param alias
385 	 *          the alias of value in it's string form
386 	 * @return the corresponding code to the specified alias.
387 	 */
388 	public static int getInt(String alias) {
389 		Integer value = getValue(alias);
390 		if (value == null) {
391 			XmlConfiguration.error++;
392 			System.out.println("\t>> Unknown integer value : " + alias);
393 			return 0;
394 		}
395 		return value;
396 	}
397 
398 	/***
399 	 * Return the corresponding code to the card color name
400 	 * 
401 	 * @param alias
402 	 *          the alias name.
403 	 * @return the alias value
404 	 */
405 	public static int getAliasValue(String alias) {
406 		int value = aliasMap.get(alias);
407 		if (value == Integer.MIN_VALUE) {
408 			// alias not found
409 			value = 0;
410 			XmlConfiguration.error++;
411 			System.out.println("\t>> Unknown alias value '" + alias + "'");
412 		}
413 		return value;
414 	}
415 
416 	/***
417 	 * Return the corresponding code to the card color name
418 	 * 
419 	 * @param colorName
420 	 *          the color alias
421 	 * @return the corresponding code to the card color name
422 	 */
423 	public static int getColor(String colorName) {
424 		final Object obj = XmlTools.cardColorsName.get(colorName);
425 		if (obj != null) {
426 			return ((Integer) obj).intValue();
427 		}
428 		XmlConfiguration.error++;
429 		System.out.println("\t>> Unknown color : '" + colorName + "'");
430 		return 0;
431 	}
432 
433 	/***
434 	 * Return the corresponding code to the card type name
435 	 * 
436 	 * @param idCard
437 	 *          the card type name
438 	 * @return the corresponding code to the card type name
439 	 */
440 	public static int getIdCard(String idCard) {
441 		final int value = aliasMap.get(idCard);
442 		if (value == Integer.MIN_VALUE) {
443 			// alias not found
444 			XmlConfiguration.error++;
445 			System.out.println("\t>> Unknown idcard : '" + idCard + "'");
446 			return 0;
447 		}
448 		return value;
449 	}
450 
451 	/***
452 	 * Return the corresponding code to the list of card type name
453 	 * 
454 	 * @param list
455 	 *          is the list of card type name
456 	 * @return the corresponding code to the list of card type name.
457 	 */
458 	public static int getIdCards(String list) {
459 		// idcard
460 		int idCard = 0;
461 		final String[] arrayid = list.split(" ");
462 		for (String id : arrayid) {
463 			idCard |= XmlTools.getIdCard(id);
464 		}
465 		return idCard;
466 	}
467 
468 	/***
469 	 * Write to the specified output stream the values defined as linear list ' '
470 	 * separated values, or 'value' elements.
471 	 * 
472 	 * @param out
473 	 *          outputstream where the card structure will be saved
474 	 * @param node
475 	 *          the XML test container structure
476 	 * @param tagAttr
477 	 * @throws IOException
478 	 *           error while writting.
479 	 */
480 	public static void writeList(OutputStream out, XmlParser.Node node,
481 			String tagAttr) throws IOException {
482 		if (node == null) {
483 			out.write(ListType.COLLECTION.ordinal());
484 			out.write(0);
485 			return;
486 		}
487 		final String listName;
488 		if (tagAttr.endsWith("y")) {
489 			listName = tagAttr + "ies";
490 		} else {
491 			listName = tagAttr + "s";
492 		}
493 		final String nodeAttr = node.getAttribute(listName);
494 		if (nodeAttr != null) {
495 			// TODO Support the java list and reference value
496 
497 			// the value is directly specified : linear list / range
498 			final String[] values;
499 			if (nodeAttr.indexOf("..") != -1) {
500 				out.write(ListType.RANGE.ordinal());
501 				values = nodeAttr.split("//.//.");
502 			} else {
503 				out.write(ListType.COLLECTION.ordinal());
504 				values = nodeAttr.split(" ");
505 			}
506 			out.write(values.length);
507 			for (String value : values) {
508 				writeSimpleValue(out, value);
509 			}
510 		} else {
511 			// the value is defined if an inner-element, it's a complex value
512 			out.write(ListType.COLLECTION.ordinal());
513 			Node valuesNode = node.get(listName);
514 			if (valuesNode == null) {
515 				out.write(0);
516 			} else {
517 				final List<Node> values = valuesNode.getNodes("value");
518 				out.write(values.size());
519 				for (XmlParser.Node value : values) {
520 					writeComplexValue(out, value);
521 				}
522 			}
523 		}
524 	}
525 
526 	/***
527 	 * Write to the specified output stream the 16bits integer value.
528 	 * 
529 	 * @param out
530 	 *          outputstream where the card structure will be saved
531 	 * @param value
532 	 *          the simple value to write.
533 	 * @throws IOException
534 	 *           error while writting.
535 	 */
536 	public static void writeSimpleValue(OutputStream out, String value)
537 			throws IOException {
538 		final AbstractValue abstractValue = AbstractValue.valueOfXsd(value);
539 		if (abstractValue != null) {
540 			out.write(IdOperations.ABSTRACT_VALUE);
541 			abstractValue.serialize(out);
542 		} else {
543 			TestOn testOn = TestOn.valueOfXsd(value);
544 			if (testOn != null) {
545 				out.write(IdOperations.TEST_ON);
546 				testOn.serialize(out);
547 			} else {
548 				Integer intValue = getIntPriv(value);
549 				if (intValue == null) {
550 					XmlConfiguration.error++;
551 					System.out.println("\t>> Unknown alias : '" + value + "'");
552 					writeConstant(out, 0);
553 				} else {
554 					writeConstant(out, intValue);
555 				}
556 			}
557 		}
558 	}
559 
560 	/***
561 	 * Write to the specified output stream the 16bits integer value.
562 	 * 
563 	 * @param out
564 	 *          outputstream where the card structure will be saved
565 	 * @param value
566 	 *          the simple value to write.
567 	 * @throws IOException
568 	 *           error while writting.
569 	 */
570 	public static void writeConstant(OutputStream out, int value)
571 			throws IOException {
572 		out.write(IdOperations.INT_VALUE);
573 		MToolKit.writeInt16(out, getNegativeConstant(value));
574 	}
575 
576 	/***
577 	 * @param out
578 	 *          outputstream where the card structure will be saved
579 	 * @param expr
580 	 *          complex expression node to write
581 	 * @throws IOException
582 	 *           error while writting.
583 	 */
584 	public static void writeComplexValue(OutputStream out, XmlParser.Node expr)
585 			throws IOException {
586 		// try getting the value as register access : register name + index
587 		String register = expr.getAttribute("register");
588 		if (register != null) {
589 			if ("true".equals(expr.getAttribute("base")))
590 				out.write(IdOperations.BASE_REGISTER_INT_VALUE);
591 			else
592 				out.write(IdOperations.REGISTER_ACCESS);
593 			Register.valueOfXsd(register).serialize(out);
594 			writeAttrOptions(expr, "index", out);
595 		} else {
596 			// this is a complex expression : add, minus, method, counter, ...
597 			final Iterator<?> it = expr.iterator();
598 			while (it.hasNext()) {
599 				Object obj = it.next();
600 				if (obj instanceof XmlParser.Node) {
601 					XmlExpression.getExpression(((XmlParser.Node) obj).getTag())
602 							.buildMdb((XmlParser.Node) obj, out);
603 					return;
604 				}
605 			}
606 			XmlConfiguration.error++;
607 			System.out
608 					.println("\t>> Element '"
609 							+ expr.getParent().getTag()
610 							+ "' must contain a complex operation, or have value defined as attribute. Context="
611 							+ expr.getParent());
612 		}
613 
614 	}
615 
616 	/***
617 	 * @param node
618 	 *          the XML test container structure
619 	 * @param tagAttr
620 	 * @param out
621 	 *          outputstream where the card structure will be saved
622 	 * @throws IOException
623 	 *           error while writting.
624 	 */
625 	public static void writeAttrOptions(XmlParser.Node node, String tagAttr,
626 			OutputStream out) throws IOException {
627 		writeAttrOptionsDefault(node, tagAttr, out, null);
628 	}
629 
630 	/***
631 	 * @param node
632 	 *          the XML test container structure
633 	 * @param tagAttr
634 	 * @param out
635 	 *          outputstream where the card structure will be saved
636 	 * @param defaultValue
637 	 *          the default value to use if neither attribute, neither element has
638 	 *          been found.
639 	 * @throws IOException
640 	 *           error while writting.
641 	 */
642 	public static void writeAttrOptionsDefault(XmlParser.Node node,
643 			String tagAttr, OutputStream out, String defaultValue) throws IOException {
644 		if (defaultValue != null && node.getAttribute(tagAttr) == null
645 				&& node.get(tagAttr) == null) {
646 			node.addAttribute(new XmlParser.Attribute(tagAttr, defaultValue));
647 		}
648 		final String nodeAttr = node.getAttribute(tagAttr);
649 		if (nodeAttr != null) {
650 			// the value is directly specified : simple integer or register access
651 			if (node.getAttribute(tagAttr + "-class") != null
652 					&& !int.class.getName().equals(node.getAttribute(tagAttr + "-class"))
653 					&& !Integer.class.getName().equals(
654 							node.getAttribute(tagAttr + "-class"))) {
655 				// No integer expression
656 				out.write(IdOperations.OBJECT_VALUE);
657 				MToolKit.writeString(out, node.getAttribute(tagAttr + "-class"));
658 				MToolKit.writeString(out, node.getAttribute(tagAttr));
659 			} else if (nodeAttr.startsWith("%")) {
660 				// This is reference value
661 				out.write(IdOperations.REF_VALUE);
662 				MToolKit.writeString(out, nodeAttr);
663 			} else {
664 				writeSimpleValue(out, nodeAttr);
665 			}
666 		} else {
667 			// the value is defined if an inner-element, it's a complex value
668 			final XmlParser.Node expr = node.get(tagAttr);
669 			if (expr == null) {
670 				XmlConfiguration.error++;
671 				System.out.println("\t>> Neither element '" + tagAttr
672 						+ "' neither attribute '" + tagAttr
673 						+ "' have been found in element '" + node.getTag()
674 						+ "'.\n\t Context:\n" + node);
675 				return;
676 			}
677 			writeComplexValue(out, expr);
678 		}
679 	}
680 
681 	/***
682 	 * @param node
683 	 * @param tagAttr
684 	 * @param out
685 	 * @param nameSpace
686 	 * @throws IOException
687 	 *           error while writting.
688 	 */
689 	public static void writeAttrOptions(XmlParser.Node node, String tagAttr,
690 			OutputStream out, String nameSpace) throws IOException {
691 		final String colorAttr = node.getAttribute(tagAttr);
692 		if (colorAttr != null) {
693 			final String method = "get" + StringUtils.capitalize(nameSpace);
694 			try {
695 				final Integer retVal = (Integer) XmlTools.class.getMethod(method,
696 						String.class).invoke(null, colorAttr);
697 				if (retVal == null) {
698 					XmlConfiguration.error++;
699 					System.out.println("\t>> Unknown " + nameSpace + " : '" + colorAttr
700 							+ "'");
701 					writeConstant(out, 0);
702 				} else {
703 					writeConstant(out, retVal);
704 				}
705 			} catch (Throwable e2) {
706 				XmlConfiguration.error++;
707 				System.out.println("\t>> Error found in 'get" + nameSpace + "' : "
708 						+ e2.getMessage());
709 				writeConstant(out, 0);
710 			}
711 		} else {
712 			final XmlParser.Node expr = node.get(tagAttr);
713 			if (expr == null) {
714 				XmlConfiguration.error++;
715 				System.out.println("\t>> Neither element '" + tagAttr
716 						+ "' neither attribute '" + tagAttr
717 						+ "' have been found in element '" + node.getTag() + "'. Context="
718 						+ node);
719 				return;
720 			}
721 			writeComplexValue(out, expr);
722 		}
723 	}
724 
725 	/***
726 	 * @param attribute
727 	 *          the message name.
728 	 * @return the message id.
729 	 */
730 	public static IdMessageBox getMessageType(String attribute) {
731 		if (attribute == null) {
732 			return IdMessageBox.ok;
733 		}
734 		IdMessageBox messageBox = IdMessageBox.valueOf(attribute);
735 		if (messageBox == null) {
736 			return IdMessageBox.ok;
737 		}
738 		return messageBox;
739 	}
740 
741 	/***
742 	 * The definied user alias
743 	 */
744 	public static Map<String, Integer> aliasMap = null;
745 
746 	/***
747 	 * This field must be set by activated ability, triggered, and counters to
748 	 * known the default value for the 'on' attribute
749 	 */
750 	public static boolean defaultOnMeTag;
751 
752 	/***
753 	 * This field must be set by actions needing some pre-check test such as
754 	 * target action. When is <code>true</code>, the last build test does not
755 	 * refer to a ability's runtime register such as 'stack' register.
756 	 */
757 	public static boolean testCanBePreempted;
758 
759 	/***
760 	 * Return the named node from the given node. This node may be definied in an
761 	 * externalized xml file.
762 	 * 
763 	 * @param node
764 	 *          the parent node.
765 	 * @param nodeName
766 	 *          the node name.
767 	 * @return the named node from the given node.
768 	 */
769 	public static Node getExternalizableNode(Node node, String nodeName) {
770 		final Node references = node.get(nodeName);
771 		if (references.getAttribute("file") != null) {
772 			// Load the references file
773 			try {
774 				return new XmlParser().parse(references.getAttribute("file"));
775 			} catch (Exception e) {
776 				throw new RuntimeException(e);
777 			}
778 		}
779 		return references;
780 	}
781 }