Java tutorial
/* * Firemox is a turn based strategy simulator * Copyright (C) 2003-2007 Fabrice Daugan * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sf.firemox.xml.tbs; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import net.sf.firemox.modifier.ModifierType; import net.sf.firemox.operation.IdOperation; import net.sf.firemox.token.IdPropertyType; import net.sf.firemox.token.IdTokens; import net.sf.firemox.token.IdZones; import net.sf.firemox.tools.MToolKit; import net.sf.firemox.tools.PairStringInt; import net.sf.firemox.ui.component.CardPropertiesPanel; import net.sf.firemox.xml.XmlAction; import net.sf.firemox.xml.XmlConfiguration; import net.sf.firemox.xml.XmlModifier; import net.sf.firemox.xml.XmlParser; import net.sf.firemox.xml.XmlTbs; import net.sf.firemox.xml.XmlTest; import net.sf.firemox.xml.XmlToMDB; import net.sf.firemox.xml.XmlTools; import net.sf.firemox.xml.XmlParser.Node; import org.apache.commons.io.FilenameUtils; /** * This class represents an implementation of the XmlToMDB interface that * converts a XML tbs node to its binary form to the given OutputSource. * * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan</a> * @since 0.82 * @since 0.83 damage types are exported */ public class Tbs implements XmlToMDB { /** * Converts the given tbs XML node to its binary form writing in the given * OutputStream. * * @see net.sf.firemox.token.IdTokens#PLAYER_REGISTER_SIZE * @see net.sf.firemox.stack.phasetype.PhaseType * @see net.sf.firemox.clickable.ability.SystemAbility * @see net.sf.firemox.tools.StatePicture * @param node * the XML card structure * @param out * output stream where the card structure will be saved * @return the amount of written action in the output. * @throws IOException * error during the writing. * @see net.sf.firemox.deckbuilder.MdbLoader#loadMDB(String, int) */ public final int buildMdb(Node node, OutputStream out) throws IOException { final FileOutputStream fileOut = (FileOutputStream) out; referencedTest = new HashMap<String, Node>(); referencedAbilities = new HashMap<String, Node>(); referencedActions = new HashMap<String, List<Node>>(); referencedAttachments = new HashMap<String, Node>(); referencedNonMacroActions = new HashSet<String>(); referencedNonMacroAttachments = new HashSet<String>(); macroActions = new Stack<List<Node>>(); resolveReferences = false; MToolKit.writeString(out, node.getAttribute("name")); System.out.println("Building " + node.getAttribute("name") + " rules..."); MToolKit.writeString(out, node.getAttribute("version")); MToolKit.writeString(out, node.getAttribute("author")); MToolKit.writeString(out, node.getAttribute("comment")); // Write database configuration final Node database = node.get("database-properties"); Map<String, IdPropertyType> properties = new HashMap<String, IdPropertyType>(); for (java.lang.Object obj : database) { if (obj instanceof Node) { Node nodePriv = (Node) obj; String propertyType = nodePriv.getAttribute("type"); IdPropertyType propertyId; if (propertyType == null || propertyType.equals(String.class.getName())) { if ("true".equalsIgnoreCase(nodePriv.getAttribute("translate"))) { propertyId = IdPropertyType.SIMPLE_TRANSLATABLE_PROPERTY; } else { propertyId = IdPropertyType.SIMPLE_PROPERTY; } } else if ("java.util.List".equals(propertyType)) { if ("true".equalsIgnoreCase(nodePriv.getAttribute("translate"))) { propertyId = IdPropertyType.COLLECTION_TRANSLATABLE_PROPERTY; } else { propertyId = IdPropertyType.COLLECTION_PROPERTY; } } else { throw new InternalError("Unknow property type '" + propertyType + "'"); } properties.put(nodePriv.getAttribute("name"), propertyId); } } out.write(properties.size()); for (Map.Entry<String, IdPropertyType> entry : properties.entrySet()) { entry.getValue().serialize(out); MToolKit.writeString(out, entry.getKey()); } MToolKit.writeString(out, node.getAttribute("art-url")); MToolKit.writeString(out, node.getAttribute("back-picture")); MToolKit.writeString(out, node.getAttribute("damage-picture")); MToolKit.writeString(out, (String) node.get("licence").get(0)); // Manas final Node manas = node.get("mana-symbols"); // Colored manas final Node colored = manas.get("colored"); MToolKit.writeString(out, colored.getAttribute("url")); MToolKit.writeString(out, colored.getAttribute("big-url")); for (java.lang.Object obj : colored) { if (obj instanceof Node) { Node nodePriv = (Node) obj; out.write(XmlTools.getValue(nodePriv.getAttribute("name"))); MToolKit.writeString(out, nodePriv.getAttribute("picture")); MToolKit.writeString(out, nodePriv.getAttribute("big-picture")); } } // Colorless manas final Node colorless = manas.get("colorless"); MToolKit.writeString(out, colorless.getAttribute("url")); MToolKit.writeString(out, colorless.getAttribute("big-url")); MToolKit.writeString(out, colorless.getAttribute("unknown")); out.write(colorless.getNbNodes()); for (java.lang.Object obj : colorless) { if (obj instanceof Node) { final Node nodePriv = (Node) obj; out.write(Integer.parseInt(nodePriv.getAttribute("amount"))); MToolKit.writeString(out, nodePriv.getAttribute("picture")); } } // Hybrid manas final Node hybrid = manas.get("hybrid"); MToolKit.writeString(out, hybrid.getAttribute("url")); for (Object obj : hybrid) { if (obj instanceof Node) { final Node nodePriv = (Node) obj; out.write(XmlTools.getValue(nodePriv.getAttribute("name"))); MToolKit.writeString(out, nodePriv.getAttribute("picture")); } } // phyrexian manas final Node phyrexian = manas.get("phyrexian"); MToolKit.writeString(out, phyrexian.getAttribute("url")); for (Object obj : phyrexian) { if (obj instanceof Node) { final Node nodePriv = (Node) obj; out.write(XmlTools.getValue(nodePriv.getAttribute("name"))); MToolKit.writeString(out, nodePriv.getAttribute("picture")); } } // Prepare the shortcut to card's bytes offset final long shortcutCardBytes = fileOut.getChannel().position(); MToolKit.writeInt24(out, 0); // Write the user defined deck constraints final Set<String> definedConstraints = new HashSet<String>(); final Node deckConstraintRoot = XmlTools.getExternalizableNode(node, "deck-constraints"); final List<Node> deckConstraints = deckConstraintRoot.getNodes("deck-constraint"); XmlTools.writeAttrOptions(deckConstraintRoot, "deckbuilder-min-property", out); XmlTools.writeAttrOptions(deckConstraintRoot, "deckbuilder-max-property", out); XmlTools.writeAttrOptions(deckConstraintRoot, "master", out); out.write(deckConstraints.size()); for (Node deckConstraint : deckConstraints) { // Write the constraint key name String deckName = deckConstraint.getAttribute("name"); MToolKit.writeString(out, deckName); // Write extend String extend = deckConstraint.getAttribute("extends"); MToolKit.writeString(out, extend); if (extend != null && extend.length() > 0 && !definedConstraints.contains(extend)) { throw new RuntimeException("'" + deckName + "' is supposed extending '" + extend + "' but has not been found. Note that declaration order is important."); } // Write the constraint XmlTools.defaultOnMeTag = false; XmlTest.getTest("test").buildMdb(deckConstraint, out); definedConstraints.add(deckName); } // END OF HEADER // additional zones final List<XmlParser.Node> additionalZones = node.get("layouts").get("zones").get("additional-zones") .getNodes("additional-zone"); out.write(additionalZones.size()); int zoneId = IdZones.FIRST_ADDITIONAL_ZONE; for (XmlParser.Node additionalZone : additionalZones) { final String zoneName = additionalZone.getAttribute("name"); if (zoneId > IdZones.LAST_ADDITIONAL_ZONE) { throw new RuntimeException( "Cannot add more additional-zone (" + zoneName + "), increase core limitation"); } XmlTools.zones.put(zoneName, zoneId++); MToolKit.writeString(out, zoneName); MToolKit.writeString(out, additionalZone.getAttribute("layout-class")); MToolKit.writeString(out, additionalZone.getAttribute("constraint-you")); MToolKit.writeString(out, additionalZone.getAttribute("constraint-opponent")); } // Initial zone id out.write(XmlTools.getZone(node.get("layouts").get("zones").getAttribute("default-zone"))); // the references final Node references = XmlTools.getExternalizableNode(node, "references"); // the tests references System.out.println("\tshared tests..."); XmlTools.defaultOnMeTag = true; final Node tests = references.get("tests"); if (tests == null) { out.write(0); } else { out.write(tests.getNbNodes()); for (java.lang.Object obj : tests) { if (obj instanceof Node) { String ref = ((Node) obj).getAttribute("reference-name").toString(); referencedTest.put(ref, (Node) obj); MToolKit.writeString(out, ref); for (java.lang.Object objTest : (Node) obj) { if (objTest instanceof Node) { final Node node1 = (Node) objTest; try { XmlTest.getTest(node1.getTag()).buildMdb(node1, out); } catch (Throwable ie) { XmlConfiguration.error("In referenced test '" + ref + "' : " + ie.getMessage() + ". Context=" + objTest); } break; } } } } } // the action references (not included into MDB) final Node actions = references.get("actions"); System.out.print("\tactions : references (inlined in MDB)"); if (actions != null) { for (java.lang.Object obj : actions) { if (obj instanceof Node) { final String ref = ((Node) obj).getAttribute("reference-name"); final String globalName = ((Node) obj).getAttribute("name"); // do not accept macro? if ("false".equals(((Node) obj).getAttribute("macro"))) { referencedNonMacroActions.add(ref); } final List<Node> actionList = new ArrayList<Node>(); boolean firstIsDone = false; for (java.lang.Object actionI : (Node) obj) { if (actionI instanceof Node) { final Node action = (Node) actionI; // add action to the action list and replace the name of // sub-actions if (action.getAttribute("name") == null) { if (globalName != null) { if (firstIsDone) { action.addAttribute(new XmlParser.Attribute("name", "%" + globalName)); } else { action.addAttribute(new XmlParser.Attribute("name", globalName)); firstIsDone = true; } } else if (firstIsDone) { action.addAttribute(new XmlParser.Attribute("name", "%" + ref)); } else { action.addAttribute(new XmlParser.Attribute("name", ref)); firstIsDone = true; } } else if (!firstIsDone) { firstIsDone = true; } actionList.add((Node) actionI); } } // add this reference referencedActions.put(ref, actionList); } } } // the attachment references (not included into MDB) final Node attachments = references.get("attachments"); System.out.print(", attachments"); if (attachments != null) { for (java.lang.Object obj : attachments) { if (obj instanceof Node) { final String ref = ((Node) obj).getAttribute("reference-name"); // do not accept macro? if ("false".equals(((Node) obj).getAttribute("macro"))) { referencedNonMacroAttachments.add(ref); } // add this reference referencedAttachments.put(ref, (Node) obj); } } } // action pictures final Node actionsPictures = node.get("action-pictures"); System.out.print(", pictures"); if (actionsPictures == null) { out.write(0); out.write('\0'); } else { MToolKit.writeString(out, actionsPictures.getAttribute("url")); out.write(actionsPictures.getNbNodes()); for (java.lang.Object obj : actionsPictures) { if (obj instanceof Node) { final Node actionPicture = (Node) obj; MToolKit.writeString(out, actionPicture.getAttribute("name")); MToolKit.writeString(out, actionPicture.getAttribute("picture")); } } } // constraints on abilities linked to action final Node constraints = node.get("action-constraints"); System.out.println(", constraints"); if (constraints == null) { out.write(0); } else { out.write(constraints.getNbNodes()); for (java.lang.Object obj : constraints) { if (obj instanceof Node) { final Node constraint = (Node) obj; for (java.lang.Object objA : constraint.get("actions")) { if (objA instanceof Node) { XmlAction.getAction(((Node) objA).getTag()).buildMdb((Node) objA, out); break; } } if ("or".equals(constraint.getAttribute("operation"))) { IdOperation.OR.serialize(out); } else { IdOperation.AND.serialize(out); } XmlTest.getTest("test").buildMdb(constraint.get("test"), out); } } } // objects defined in this TBS System.out.println("\tobjects..."); final List<Node> objects = node.get("objects").getNodes("object"); out.write(objects.size()); for (Node object : objects) { // write object final XmlParser.Attribute objectName = new XmlParser.Attribute("name", object.getAttribute("name")); boolean onePresent = false; for (java.lang.Object modifierTmp : object) { if (modifierTmp instanceof Node) { // write the 'has-next' flag if (onePresent) { out.write(1); } // write the object-modifier final Node modifier = (Node) modifierTmp; modifier.addAttribute(objectName); XmlModifier.getModifier(modifier.getTag()).buildMdb(modifier, out); // Write the 'paint' flag if (onePresent) { out.write(0); } else { out.write(1); } onePresent = true; } } if (!onePresent) { // no modifier associated to this object, we write a virtual ONE ModifierType.REGISTER_MODIFIER.serialize(out); XmlModifier.buildMdbModifier(object, out); // Write the modified register index && value XmlTools.writeConstant(out, 0); XmlTools.writeConstant(out, 0); IdOperation.ADD.serialize(out); // Write the 'paint' flag out.write(1); } // Write the 'has-next' flag out.write(0); } // the abilities references System.out.println("\tshared abilities..."); Node abilities = references.get("abilities"); out.write(abilities.getNbNodes()); macroActions.push(null); for (Node ability : abilities.getNodes("ability")) { String ref = ability.getAttribute("reference-name").toString(); referencedAbilities.put(ref, ability); MToolKit.writeString(out, ref); try { Node node1 = (Node) ability.get(1); XmlTbs.getTbsComponent(node1.getTag()).buildMdb(node1, out); } catch (Throwable ie) { XmlConfiguration.error("Error In referenced ability '" + ref + "' : " + ie.getMessage() + "," + ie + ". Context=" + ability); } } macroActions.pop(); // damage types name System.out.println("\tdamage types..."); Collections.sort(XmlConfiguration.EXPORTED_DAMAGE_TYPES); int count = XmlConfiguration.EXPORTED_DAMAGE_TYPES.size(); out.write(count); for (int i = 0; i < count; i++) { final PairStringInt pair = XmlConfiguration.EXPORTED_DAMAGE_TYPES.get(i); MToolKit.writeString(out, pair.text); MToolKit.writeInt16(out, pair.value); } /** * <ul> * CARD'S PART : * <li>state pictures * <li>tooltip filters * <li>exported types name * <li>exported sorted properties name * <li>implemented cards * </ul> */ // state pictures System.out.println("\tstates"); final Node states = node.get("state-pictures"); if (states == null) { out.write(0); } else { out.write(states.getNbNodes()); for (java.lang.Object obj : states) { if (obj instanceof Node) { final Node ns = (Node) obj; MToolKit.writeString(out, ns.getAttribute("picture")); MToolKit.writeString(out, ns.getAttribute("name")); MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("state"))); out.write(XmlTools.getInt(ns.getAttribute("index"))); final int x = XmlTools.getInt(ns.getAttribute("x")); final int y = XmlTools.getInt(ns.getAttribute("y")); if (MToolKit.getConstant(x) == -1 && MToolKit.getConstant(y) != -1 || MToolKit.getConstant(x) != -1 && MToolKit.getConstant(y) == -1) { XmlConfiguration.error( "In state-picture '-1' value is allowed if and only if x AND y have this value."); } MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("x"))); MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("y"))); MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("width"))); MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("height"))); XmlTest.getTest("test").buildMdb(node.get("display-test"), out); } } } // tooltip filters System.out.println("\ttooltip filters..."); final Node ttFilters = node.get("tooltip-filters"); XmlTools.defaultOnMeTag = false; if (ttFilters == null) { out.write(0); } else { out.write(ttFilters.getNbNodes()); for (java.lang.Object obj : ttFilters) { if (obj instanceof Node) { buildMdbTooltipFilter((Node) obj, out); } } } // exported types name System.out.println("\texported type..."); Collections.sort(XmlConfiguration.EXPORTED_TYPES); int nbTypes = XmlConfiguration.EXPORTED_TYPES.size(); out.write(nbTypes); for (int i = 0; i < nbTypes; i++) { final PairStringInt pair = XmlConfiguration.EXPORTED_TYPES.get(i); MToolKit.writeString(out, pair.text); MToolKit.writeInt16(out, pair.value); } // exported sorted properties name and associated pictures System.out.println("\tproperties..."); Collections.sort(XmlConfiguration.EXPORTED_PROPERTIES); final int nbProperties = XmlConfiguration.EXPORTED_PROPERTIES.size(); MToolKit.writeInt16(out, nbProperties); for (int i = 0; i < nbProperties; i++) { final PairStringInt pair = XmlConfiguration.EXPORTED_PROPERTIES.get(i); MToolKit.writeInt16(out, pair.value); MToolKit.writeString(out, pair.text); } MToolKit.writeInt16(out, XmlConfiguration.PROPERTY_PICTURES.size()); for (Map.Entry<Integer, String> entry : XmlConfiguration.PROPERTY_PICTURES.entrySet()) { MToolKit.writeInt16(out, entry.getKey()); MToolKit.writeString(out, entry.getValue()); } /** * <ul> * STACK MANAGER'S PART : * <li>first player registers * <li>second player registers * <li>abortion zone * </ul> */ // player registers System.out.println("\tinitial registers..."); Node registers = node.get("registers-first-player"); final byte[] registersBytes = new byte[IdTokens.PLAYER_REGISTER_SIZE]; if (registers != null) { final List<Node> list = registers.getNodes("register"); for (Node register : list) { registersBytes[XmlTools.getInt(register.getAttribute("index"))] = (byte) XmlTools .getInt(register.getAttribute("value")); } } out.write(registersBytes); registers = node.get("registers-second-player"); final byte[] registersBytes2 = new byte[IdTokens.PLAYER_REGISTER_SIZE]; if (registers != null) { final List<Node> list = registers.getNodes("register"); for (Node register : list) { registersBytes2[XmlTools.getInt(register.getAttribute("index"))] = (byte) XmlTools .getInt(register.getAttribute("value")); } } out.write(registersBytes2); /* * TODO abortion zone */ final Node refAbilities = node.get("abilities"); out.write(XmlTools.getZone(refAbilities.getAttribute("abortionzone"))); // additional costs System.out.println("\tadditional-costs..."); final List<Node> additionalCosts = node.get("additional-costs").getNodes("additional-cost"); out.write(additionalCosts.size()); for (Node additionalCost : additionalCosts) { XmlTest.getTest("test").buildMdb(additionalCost.get("test"), out); XmlTbs.writeActionList(additionalCost.get("cost"), out); } /** * <ul> * EVENT MANAGER'S PART : * <li>phases * <li>turn-structure * <li>first phase index * </ul> */ // phases System.out.println("\tphases..."); final Node phases = node.get("phases"); out.write(phases.getNbNodes()); for (java.lang.Object obj : phases) { if (obj instanceof Node) { buildMdbPhaseType((Node) obj, out); } } // turn structure final String list = phases.getAttribute("turn-structure"); System.out.println("\tturn structure..."); final String[] arrayid = list.split(" "); out.write(arrayid.length); for (String id : arrayid) { out.write(XmlTools.getAliasValue(id)); } // first phase index for first turn out.write(Integer.parseInt(phases.getAttribute("start"))); // state based abilities System.out.println("\trule abilities..."); out.write(refAbilities.getNbNodes()); for (java.lang.Object obj : refAbilities) { if (obj instanceof Node) { try { XmlTbs.getTbsComponent(((Node) obj).getTag()).buildMdb((Node) obj, out); } catch (Throwable ie) { XmlConfiguration.error("Error in system ability '" + ((Node) obj).getAttribute("name") + "' : " + ie.getMessage() + ". Context=" + obj); break; } } } // static-modifiers System.out.println("\tstatic-modifiers..."); final Node modifiers = node.get("static-modifiers"); if (modifiers == null) { out.write(0); } else { out.write(modifiers.getNbNodes()); for (java.lang.Object obj : modifiers) { if (obj instanceof Node) { XmlModifier.getModifier("static-modifier").buildMdb((Node) obj, out); } } } // layouts System.out.println("\tlayouts..."); final Node layouts = node.get("layouts"); // initialize task pane layout writeTaskPaneElement(layouts.get("common-panel").get("card-details").get("properties"), out); // Sector of play zone for layouts List<Node> sectors = layouts.get("zones").get("play").getNodes("sector"); out.write(sectors.size()); for (XmlParser.Node sector : sectors) { XmlTest.getTest("test").buildMdb(sector, out); MToolKit.writeString(out, sector.getAttribute("constraint")); } // Update the shortcut to the first bytes of cards final long cardBytesPosition = fileOut.getChannel().position(); fileOut.getChannel().position(shortcutCardBytes); MToolKit.writeInt24(out, (int) cardBytesPosition); fileOut.getChannel().position(cardBytesPosition); // cards bytes + names resolveReferences = true; System.out.println("Processing cards..."); String xmlFile = node.getAttribute("xmlFile"); try { final String baseName = FilenameUtils.getBaseName(xmlFile); XmlTbs.updateMdb(baseName, out); } catch (Throwable e2) { XmlConfiguration.error("Error found in cards parsing of rule '" + xmlFile + "' : " + e2.getMessage()); } System.out.println(node.getAttribute("name") + " rules finished"); return 0; } private void writeTaskPaneElement(Node node, OutputStream out) throws IOException { final List<Node> elements = node.getNodes("menu-element"); final List<Node> attributes = node.getNodes("menu-attribute"); out.write((elements == null ? 0 : elements.size()) + (attributes == null ? 0 : attributes.size())); for (java.lang.Object nestedNode : node) { if (nestedNode instanceof Node) { final Node task = (Node) nestedNode; if ("menu-element".equals(task.getTag())) { out.write(CardPropertiesPanel.NESTED_ELEMENT); MToolKit.writeString(out, task.getAttribute("name")); writeTaskPaneElement(task, out); } else if ("menu-attribute".equals(task.getTag())) { out.write(CardPropertiesPanel.ATTRIBUTE); MToolKit.writeString(out, task.getAttribute("type").toLowerCase()); MToolKit.writeString(out, task.getAttribute("name")); MToolKit.writeString(out, task.getAttribute("value")); } else { XmlConfiguration.warning("non supported task type : " + task.getTag()); } } } } /** * <ul> * Structure of stream : Data[size] * <li>phase name + '\0' [...]</li> * <li>phase identifier [1]</li> * <li>empty stack playable, idCards for current player [2]</li> * <li>empty stack playable, idCards for non-current player [2]</li> * <li>middle resolution, playable idCards for current player [2]</li> * <li>middle resolution, playable idCards for non-current player [2]</li> * </ul> * * @param node * the XML phase type structure * @param out * output stream where the card structure will be saved * @throws IOException * error during the * @see net.sf.firemox.stack.phasetype.PhaseType */ public static final void buildMdbPhaseType(Node node, OutputStream out) throws IOException { MToolKit.writeString(out, node.getAttribute("name")); out.write(XmlTools.getAliasValue(node.getAttribute("name"))); MToolKit.writeInt16(out, XmlTools.getIdCards(node.getAttribute("playable-empty-stack-you"))); MToolKit.writeInt16(out, XmlTools.getIdCards(node.getAttribute("playable-empty-stack-opponent"))); MToolKit.writeInt16(out, XmlTools.getIdCards(node.getAttribute("playable-middle-resolution-you"))); MToolKit.writeInt16(out, XmlTools.getIdCards(node.getAttribute("playable-middle-resolution-opponent"))); } /** * <ul> * Structure of stream : Data[size] * <li>display powerANDtoughness yes=1,no=0 [1]</li> * <li>display states yes=1,no=0 [1]</li> * <li>display types yes=1,no=0 [1]</li> * <li>display colors yes=1,no=0 [1]</li> * <li>display properties yes=1,no=0 [1]</li> * <li>display damage yes=1,no=0 [1]</li> * <li>filter [...]</li> * </ul> * * @param node * the XML structure * @param out * output stream where the card structure will be saved * @throws IOException * error during the writing. */ public static final void buildMdbTooltipFilter(Node node, OutputStream out) throws IOException { out.write("true".equals(node.getAttribute("powerANDtoughness")) ? 1 : 0); out.write("true".equals(node.getAttribute("states")) ? 1 : 0); out.write("true".equals(node.getAttribute("types")) ? 1 : 0); out.write("true".equals(node.getAttribute("colors")) ? 1 : 0); out.write("true".equals(node.getAttribute("properties")) ? 1 : 0); out.write("true".equals(node.getAttribute("damage")) ? 1 : 0); XmlTest.getTest("test").buildMdb(node.get("filter"), out); } /** * Push an action (accepting <code>null</code>) for macro. * * @param node * the node to give to the next macro. */ public static void pushMacroAction(List<Node> node) { macroActions.push(node); } /** * Return the last given action to a macro. * * @return the last given action to a macro. */ public static List<Node> peekMacroAction() { return macroActions.peek(); } /** * Remove the last given action to a macro. */ public static void popMacroAction() { macroActions.pop(); } /** * Available ability references of this TBS */ public static Map<String, Node> referencedAbilities = null; /** * Available test references of this TBS */ public static Map<String, Node> referencedTest = null; /** * Available actions references of this TBS */ public static Map<String, List<Node>> referencedActions = null; /** * Available actions references of this TBS do not accepting macro */ public static Set<String> referencedNonMacroActions = null; /** * Available attachments references of this TBS do not accepting macro */ public static Set<String> referencedNonMacroAttachments = null; /** * Available attachments references of this TBS. */ public static Map<String, Node> referencedAttachments = null; /** * Available node for action of macro. */ public static Stack<List<Node>> macroActions = null; /** * Are the references must be resolved. */ public static boolean resolveReferences; }