The “utils” package
1.Package Description
This package provides utility classes for evacuation visualization. The classes implemented are listed below:
- AgentLoader
- DOMParser
- EnvObjectLoader
- EventLoader
- VisResource
- VisResourcesRepository
2.Implementing package
To implement the “AgentLoader” class:
- Create a new class inside the “utils” package and name it “AgentLoader”.
- Copy the code given below that describes the full implementation of a “AgentLoader” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Node; import com.jme3.math.Vector3f; import edu.utdallas.mavs.divas.core.config.Config; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; /** * This class is used to parse the XML file that contains * the agents information, which is used later * for adding the agents */ public class AgentLoader { private static String FILE = Config.getAgentsXML(); private static Node rootNode; private static List<String> agentTypeIds; private static List<String> agentTypeNames; // Agent Attributes private static String AGENT = "agentClass"; private static String AGENT_TYPE = "agentType"; private static String AGENT_ID = "id"; private static String AGENT_NAME = "name"; private static String AGENT_MODEL_TYPE = "type"; private static String AGENT_DESCRIPTION = "description"; private static String AGENT_SCALE = "scale"; private static String AGENT_POSITION = "position"; private static String AGENT_IMAGE = "image"; private static String AGENT_MODEL_NAME = "modelName"; private static void setup() { Document doc = DOMParser.parseDocument(FILE); rootNode = doc.getDocumentElement(); agentTypeIds = DOMParser.getChildElementsAttributesByTag(rootNode, AGENT_TYPE, AGENT_ID); agentTypeNames = DOMParser.getChildElementsAttributesByTag(rootNode, AGENT_TYPE, AGENT_NAME); } /** * Gets a list of environment objects states for a specific environment object type * * @param selectionId * The agent type selected * @return A list of agent states */ public static List<AgentState> getAgentStates(int selectionId) { if(rootNode == null) { setup(); } List<AgentState> agentList = new ArrayList<AgentState>(); // Get the root XML element from the given file Node selectedTypeNode = DOMParser.getElementById(rootNode, agentTypeIds.get(selectionId)); List<Node> childList = DOMParser.getElementsByTag(selectedTypeNode, AGENT); for(int i = 0; i < childList.size(); i++) { Node node = childList.get(i); AgentState agentState = new AgentState(); agentState.setModelName(DOMParser.getAttribute(node, AGENT_MODEL_NAME)); agentState.setPosition(getVector3f(node, AGENT_POSITION)); agentState.setScale(getVector3f(node, AGENT_SCALE)); agentList.add(agentState); } return agentList; } /** * Gets a list of agents states for a specific environment object type * * @return A list of agents states */ public static List<VisResource<AgentState>> getVisResources() { if(rootNode == null) { setup(); } List<VisResource<AgentState>> agentList = new ArrayList<>(); for(String id : agentTypeIds) { // Get the root XML element from the given file Node selectedTypeNode = DOMParser.getElementById(rootNode, id); List<Node> childList = DOMParser.getElementsByTag(selectedTypeNode, AGENT); for(int i = 0; i < childList.size(); i++) { Node node = childList.get(i); AgentState agentState = new AgentState(); agentState.setModelName(DOMParser.getAttribute(node, AGENT_MODEL_NAME)); agentState.setPosition(getVector3f(node, AGENT_POSITION)); agentState.setScale(getVector3f(node, AGENT_SCALE)); VisResource<AgentState> resource = new VisResource<AgentState>(DOMParser.getAttribute(node, AGENT_IMAGE), DOMParser.getAttribute(node, AGENT_NAME), DOMParser.getAttribute(node, AGENT_MODEL_TYPE), DOMParser.getAttribute(node, AGENT_DESCRIPTION), agentState ); agentList.add(resource); } } return agentList; } /** * @return a list of agent types found in the XML file. */ public static List<String> getObjTypeNames() { if(rootNode == null) { setup(); } return agentTypeNames; } private static Vector3f getVector3f(Node node, String attribute) { List<Node> nodeChild = DOMParser.getElementsByTag(node, attribute); // note nodeChild is a list w/ one element float x = getValue(nodeChild.get(0), "x"); float y = getValue(nodeChild.get(0), "y"); float z = getValue(nodeChild.get(0), "z"); return new Vector3f(x, y, z); } private static Float getValue(Node node, String variable) { return Float.valueOf(DOMParser.getAttribute(node, variable)); } }
To implement the “DOMParser” class:
- Create a new class inside the “utils” package and name it “DOMParser”.
- Copy the code given below that describes the full implementation of a “DOMParser” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import edu.utdallas.mavs.divas.utils.ResourceManager; /** * This is a helper class for parsing XML into a tree of Node. */ public class DOMParser { /** * The {@link DOMParser} constructor. */ public DOMParser() {} /** * Gets the root XML element from the given file. * * @param file * The XML file to be parsed. * @return * The newly-created {@link Document} object. */ public static Document parseDocument(String file) { Document document = null; DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = builderFactory.newDocumentBuilder(); document = builder.parse(ResourceManager.getResourceStream(file)); } catch(ParserConfigurationException e) { e.printStackTrace(); } catch(SAXException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } return document; } /** * Retrieves an attribute value for a given node by Name. * * @param node * The node of the tree the attribute will be retrieved from. * @param name * The name of the attribute to retrieve. * @return the attribute value. */ public static String getAttribute(Node node, String name) { if(node instanceof Element) { Element element = (Element) node; // logger.debug(name + ": " +element.getAttribute(name)); return element.getAttribute(name); } return null; } /** * Returns a child {@link Element} of the {@link Node} by Id. * * @param node * The node of the tree from where the Element will be retrieved from. * @param id * The id of the element to retrieve. * @return * the Element. */ public static Element getElementById(Node node, String id) { return getElementById((Element) node, id); } /** * Returns a child {@link Element} of the given {@link Element} by Id * * @param element * An element from an XML document * @param id * The id of the element to retrieve * @return Element */ public static Element getElementById(Element element, String id) { NodeList nodeList = element.getChildNodes(); // logger.debug("nodeList length: " +nodeList.getLength()); for(int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if(node.hasAttributes() && getAttribute(node, "id").equalsIgnoreCase(id)) { // logger.debug("Node name: " +node.getNodeName()); return (Element) node; } } return null; } /** * Returns a list of child nodes of the given {@link Node} with the * given name tag. * * @param node * The node of the tree from where the child node will be retrieved from. * @param name * The name of the child node to retrieve. * @return * List of child nodes. */ public static List<Node> getElementsByTag(Node node, String name) { return getElementsByTag((Element) node, name); } /** * Returns a list of child nodes of the given {@link Element} with the * given name tag. * * @param element * The element of the tree from where the child node will be retrieved from. * @param name * The name of the child node to retrieve. * @return * List of child nodes. */ public static List<Node> getElementsByTag(Element element, String name) { List<Node> elementList = new ArrayList<Node>(); NodeList childNodes = element.getChildNodes(); // logger.debug("nodeList length: " +childNodes.getLength()); for(int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if(node.hasAttributes() && (node.getNodeName()).equalsIgnoreCase(name)) { // logger.debug("Node name: " +node.getNodeName()); elementList.add(node); } } return elementList; } /** * Returns a list of child elements of the given {@link Node} with the * given name and attribute. * * @param node * The node of the tree from where the child node will be retrieved from. * @param name * The name of the child node to retrieve. * @param attribute * The attribute of the child node to retrieve. * @return List of attributes of the child elements. */ public static List<String> getChildElementsAttributesByTag(Node node, String name, String attribute) { return getChildElementsAttributesByTag((Element) node, name, attribute); } /** * Returns a list of child elements of the given {@link Element} with the * given name and attribute. * * @param element * The element of the tree from where the child node will be retrieved from. * @param name * The name of the child node to retrieve. * @param attribute * The attribute of the child node to retrieve. * @return List of attributes of the child elements. */ public static List<String> getChildElementsAttributesByTag(Element element, String name, String attribute) { List<String> childElementStrings = new ArrayList<String>(); List<Node> nodeList = getElementsByTag(element, name); for(Node node : nodeList) { childElementStrings.add(getAttribute(node, attribute)); } return childElementStrings; } }
To implement the “EnvObjectLoader” class:
- Create a new class inside the “utils” package and name it “EnvObjectLoader”.
- Copy the code given below that describes the full implementation of a “EnvObjectLoader” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Node; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import edu.utdallas.mavs.divas.core.config.Config; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; /** * This class is used to parse the XML file that contains * the environment objects information, which is used later * for adding the environment objects */ public class EnvObjectLoader { private static String FILE = Config.getEnvObjectsXML(); private static Node rootNode; private static List<String> envObjTypeIds; private static List<String> envObjTypeNames; // Environment Object Attributes private static String ENV_OBJECT = "envObject"; private static String ENV_OBJ_TYPE = "envObjectType"; private static String ENV_OBJ_ID = "id"; private static String ENV_OBJ_NAME = "name"; private static String ENV_OBJ_MODEL_TYPE = "type"; private static String ENV_OBJ_DESCRIPTION = "description"; private static String ENV_OBJ_SCALE = "scale"; private static String ENV_OBJ_ROTATION = "rotation"; private static String ENV_OBJ_POSITION = "position"; private static String ENV_OBJ_IMAGE = "image"; private static String ENV_OBJ_MATERIAL = "material"; private static String ENV_OBJ_MODEL_NAME = "modelName"; private static String ENV_OBJ_COLLIDABLE = "collidable"; private static void setup() { Document doc = DOMParser.parseDocument(FILE); rootNode = doc.getDocumentElement(); envObjTypeIds = DOMParser.getChildElementsAttributesByTag(rootNode, ENV_OBJ_TYPE, ENV_OBJ_ID); envObjTypeNames = DOMParser.getChildElementsAttributesByTag(rootNode, ENV_OBJ_TYPE, ENV_OBJ_NAME); } /** * Gets a list of environment objects states for a specific environment object type * * @param selectionId * The id of the env object type selected * @param typeId * The main environment object type * @param rootNode * The root node for the XML file * @return A list of environment object states */ public static List<EnvObjectState> getEnvObjectStates(int selectionId) { if(rootNode == null) { setup(); } List<EnvObjectState> envObjList = new ArrayList<EnvObjectState>(); // Get the root XML element from the given file Node selectedTypeNode = DOMParser.getElementById(rootNode, envObjTypeIds.get(selectionId)); List<Node> childList = DOMParser.getElementsByTag(selectedTypeNode, ENV_OBJECT); for(int i = 0; i < childList.size(); i++) { Node node = childList.get(i); EnvObjectState envObjectState = new EnvObjectState(); envObjectState.setType(DOMParser.getAttribute(node, ENV_OBJ_MODEL_TYPE)); envObjectState.setDescription(DOMParser.getAttribute(node, ENV_OBJ_DESCRIPTION)); envObjectState.setModelName(DOMParser.getAttribute(node, ENV_OBJ_MODEL_NAME)); envObjectState.setMaterial(DOMParser.getAttribute(node, ENV_OBJ_MATERIAL)); envObjectState.setName(DOMParser.getAttribute(node, ENV_OBJ_NAME)); envObjectState.setImage(DOMParser.getAttribute(node, ENV_OBJ_IMAGE)); envObjectState.setPosition(getVector3f(node, ENV_OBJ_POSITION)); envObjectState.setRotation(getQuaternion(node, ENV_OBJ_ROTATION)); envObjectState.setScale(getVector3f(node, ENV_OBJ_SCALE)); envObjectState.setCollidable(Boolean.parseBoolean(DOMParser.getAttribute(node, ENV_OBJ_COLLIDABLE))); envObjList.add(envObjectState); } return envObjList; } /** * Gets a list of environment objects states for a specific environment object type * * @param selectionId * The id of the env object type selected * @param typeId * The main environment object type * @param rootNode * The root node for the XML file * @return A list of environment object states */ public static List<VisResource<EnvObjectState>> getVisResources() { if(rootNode == null) { setup(); } List<VisResource<EnvObjectState>> envObjList = new ArrayList<>(); for(String id : envObjTypeIds) { // Get the root XML element from the given file Node selectedTypeNode = DOMParser.getElementById(rootNode, id); List<Node> childList = DOMParser.getElementsByTag(selectedTypeNode, ENV_OBJECT); for(int i = 0; i < childList.size(); i++) { Node node = childList.get(i); EnvObjectState envObjectState = new EnvObjectState(); envObjectState.setType(DOMParser.getAttribute(node, ENV_OBJ_MODEL_TYPE)); envObjectState.setDescription(DOMParser.getAttribute(node, ENV_OBJ_DESCRIPTION)); envObjectState.setModelName(DOMParser.getAttribute(node, ENV_OBJ_MODEL_NAME)); envObjectState.setMaterial(DOMParser.getAttribute(node, ENV_OBJ_MATERIAL)); envObjectState.setName(DOMParser.getAttribute(node, ENV_OBJ_NAME)); envObjectState.setImage(DOMParser.getAttribute(node, ENV_OBJ_IMAGE)); envObjectState.setPosition(getVector3f(node, ENV_OBJ_POSITION)); envObjectState.setRotation(getQuaternion(node, ENV_OBJ_ROTATION)); envObjectState.setScale(getVector3f(node, ENV_OBJ_SCALE)); envObjectState.setCollidable(Boolean.parseBoolean(DOMParser.getAttribute(node, ENV_OBJ_COLLIDABLE))); VisResource<EnvObjectState> resource = new VisResource<EnvObjectState>(DOMParser.getAttribute(node, ENV_OBJ_IMAGE), envObjectState.getName(), envObjectState.getType(), envObjectState.getDescription(), envObjectState); envObjList.add(resource); } } return envObjList; } /** * @return a list of environment object types found in the XML file. */ public static List<String> getObjTypeNames() { if(rootNode == null) { setup(); } return envObjTypeNames; } private static Vector3f getVector3f(Node node, String attribute) { List<Node> nodeChild = DOMParser.getElementsByTag(node, attribute); // note nodeChild is a list w/ one element float x = getValue(nodeChild.get(0), "x"); float y = getValue(nodeChild.get(0), "y"); float z = getValue(nodeChild.get(0), "z"); return new Vector3f(x, y, z); } private static Quaternion getQuaternion(Node node, String attribute) { List<Node> nodeChild = DOMParser.getElementsByTag(node, attribute); // note nodeChild is a list w/ one element float x = getValue(nodeChild.get(0), "x"); float y = getValue(nodeChild.get(0), "y"); float z = getValue(nodeChild.get(0), "z"); float w = getValue(nodeChild.get(0), "w"); return new Quaternion(x, y, z, w); } private static Float getValue(Node node, String variable) { return Float.valueOf(DOMParser.getAttribute(node, variable)); } }
To implement the “EventLoader” class:
- Create a new class inside the “utils” package and name it “EventLoader”.
- Copy the code given below that describes the full implementation of a “EventLoader” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Node; import edu.utdallas.mavs.divas.core.config.Config; /** * This class is used to parse the XML file that contains * the events information, which is used later * for adding the events */ public class EventLoader { private static String FILE = Config.getEventsXML(); private static Node rootNode; // Event Attributes private static String EVENT_TYPE = "eventType"; private static String EVENT_NAME = "name"; private static String EVENT_MODE = "mode"; private static String EVENT_DESCRIPTION = "description"; private static String ENVEVENT_TYPE = "type"; private static String EVENT_IMAGE = "image"; private static void setup() { Document doc = DOMParser.parseDocument(FILE); rootNode = doc.getDocumentElement(); } /** * Gets a list of Event of event modes * * @return A list of event modes */ public static List<VisResource<Event>> getVisResources() { if(rootNode == null) { setup(); } List<VisResource<Event>> envEventList = new ArrayList<>(); // Get the root XML element from the given file List<Node> childList = DOMParser.getElementsByTag(rootNode, EVENT_TYPE); for(int i = 0; i < childList.size(); i++) { Node node = childList.get(i); Event eventMode = new Event(DOMParser.getAttribute(node, EVENT_MODE)); VisResource<Event> resource = new VisResource<Event>(DOMParser.getAttribute(node, EVENT_IMAGE), DOMParser.getAttribute(node, EVENT_NAME), DOMParser.getAttribute(node, ENVEVENT_TYPE), DOMParser.getAttribute(node, EVENT_DESCRIPTION), eventMode); envEventList.add(resource); } return envEventList; } /** * This class is for storing the input mode in the simulatingAppState when pressing an event in the 3D visualizer. */ public static class Event { String inputMode; /** * Constructs the EventMode object * * @param inputMode The inputMode to be set in the object */ public Event(String inputMode) { this.inputMode = inputMode; } /** * @return The input mode stored in the object */ public String getInputMode() { return inputMode; } } }
To implement the “VisResource” class:
- Create a new class inside the “utils” package and name it “VisResource”.
- Copy the code given below that describes the full implementation of a “VisResource” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import edu.utdallas.mavs.divas.core.sim.common.event.EnvEvent; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; /** * This class describes a visualizer resource. * * @param <T> the type of the object associated with the visualizer resource */ public class VisResource<T> { /** * The image path for resource. */ protected String image = ""; /** * The name of the resource. */ protected String name = ""; /** * The type of the resource. */ protected String type = ""; /** * The description associated with the resource. */ protected String description = ""; /** * The category of this resource. */ protected ResourceCategory category; /** * Some object associated with this resource. */ protected T object; /** * An enumeration of categories for visualizer resources */ public enum ResourceCategory { AGENT, ENV_OBJ, EVENT } /** * Constructs a new visualizer resource * * @param image the image associated with the resource * @param name the name of the resource * @param type the type of the resource * @param description the description of the resource * @param object the object associated with the resource */ public VisResource(String image, String name, String type, String description, T object) { assert (object instanceof AgentState); assert (object instanceof EnvObjectState); assert (object instanceof EnvEvent); this.image = image; this.name = name; this.type = type; this.description = description; this.object = object; this.category = getCategory(object); } /** * Gets the image of this resource * * @return the resource's image */ public String getImage() { return image; } /** * Gets the name of this resource * * @return the resource's name */ public String getName() { return name; } /** * Gets the type of this resource * * @return the resource's type */ public String getType() { return type; } /** * Gets the description of this resource * * @return the resource's description */ public String getDescription() { return description; } /** * Gets the category of this resource * * @return the resource's category */ public ResourceCategory getCategory() { return category; } /** * Gets the object of this resource * * @return the resource's object */ public T getObject() { return object; } /** * Infers this object category from its object's type * * @param object * @return */ private ResourceCategory getCategory(T object) { if(object instanceof AgentState) return ResourceCategory.AGENT; if(object instanceof EnvObjectState) return ResourceCategory.ENV_OBJ; if(object instanceof EnvEvent) return ResourceCategory.EVENT; return null; } }
To implement the “VisResourcesRepository” class:
- Create a new class inside the “utils” package and name it “VisResourcesRepository”.
- Copy the code given below that describes the full implementation of a “VisResourcesRepository” class.
package edu.utdallas.mavs.evacuation.visualization.utils; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; import edu.utdallas.mavs.evacuation.visualization.utils.EventLoader.Event; /** * This class describes a repository for visualizer resources. */ public class VisResourcesRepository { private List<VisResource<AgentState>> agents; private List<VisResource<EnvObjectState>> objects; private List<VisResource<Event>> events; private static VisResourcesRepository instance; private VisResourcesRepository() { agents = AgentLoader.getVisResources(); objects = EnvObjectLoader.getVisResources(); events = EventLoader.getVisResources(); Collections.sort(agents, new VisResourcesComparator<AgentState>()); Collections.sort(objects, new VisResourcesComparator<EnvObjectState>()); Collections.sort(events, new VisResourcesComparator<Event>()); } /** * Gets the singleton instance of this repository * * @return the singleton */ private static VisResourcesRepository getInstance() { if(instance == null) instance = new VisResourcesRepository(); return instance; } /** * Gets all agent resources * * @return a list of agent resource definitions */ public static List<VisResource<AgentState>> findAllAgents() { return getInstance().agents; } /** * Gets agent resources filtered by a given query * * @param query * a search query * @return a list of agent resource definitions */ public static List<VisResource<AgentState>> findAgents(String query) { return search(getInstance().agents, query); } /** * Gets all object resources * * @return a list of agent resource definitions */ public static List<VisResource<EnvObjectState>> findAllEnvObjects() { return getInstance().objects; } /** * Gets object resources filtered by a given query * * @param query * a search query * @return a list of agent resource definitions */ public static List<VisResource<EnvObjectState>> findEnvObjects(String query) { return search(getInstance().objects, query); } /** * Gets all event resources * * @return a list of agent resource definitions */ public static List<VisResource<Event>> findAllEvents() { return getInstance().events; } /** * Gets event resources filtered by a given query * * @param query * a search query * @return a list of agent resource definitions */ public static List<VisResource<Event>> findEvents(String query) { return search(getInstance().events, query); } private static <T> List<VisResource<T>> search(List<VisResource<T>> resources, String query) { List<VisResource<T>> results = new ArrayList<>(); String lcQuery = query.toLowerCase(); for(VisResource<T> r : resources) { if(r.getType().toLowerCase().contains(lcQuery) || r.getName().toLowerCase().contains(lcQuery) || r.getDescription().toLowerCase().contains(lcQuery)) results.add(r); } return results; } class VisResourcesComparator<T> implements Comparator<VisResource<T>> { @Override public int compare(VisResource<T> o1, VisResource<T> o2) { return o1.getName().compareTo(o2.getName()); } } }
After finish implementing this package,
