/** * @author Mauricio Araya (maray[at]inf.utfsm.cl) * @author Jorge Avarias (javarias[at]alumnos.inf.utfsm.cl) */ package cl.utfsm.acs.ebe; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.TreeMap; import org.apache.xerces.parsers.DOMParser; import org.apache.xml.serialize.Method; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.apache.xerces.dom.DocumentImpl; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import cl.utfsm.acs.types.AcsComplexType; import cl.utfsm.acs.types.ComplexObject; /** Error Browser and Editor Document object. This object is the representation * of a document (and a file). This is the start point for any client. * Each document is a ComplexObject, as all its contents. * @author Mauricio Araya (maray[at]inf.utfsm.cl) */ public class EbeDocument extends ComplexObject { /** The common DOM parser */ static private DOMParser parser; /** The class type */ protected static AcsComplexType typeType; /** The nodes (completions and errors) TreeMap */ protected TreeMap<String,ComplexObject> nodes; /** The file path */ private String path; /** The DOM document */ private Document doc; /** The class type setter */ public static void setClassType(AcsComplexType t){ typeType=t; } /** The class type getter */ public static AcsComplexType getClassType(){ return(typeType); } /** Initialize a new EbeDocument */ public EbeDocument(){ super(typeType); nodes=new TreeMap<String,ComplexObject>(); } /** Set the Path of the Document * @param path the absolute path to the file */ public void setPath(String path){ this.path=path; } /** Get the current filename Path * @return the path*/ public String getPath(){ return(path); } /** Read the node into a ComplexObject * @param no the DOM node to read * @param obj the Complex Object to fill */ private void readNode(Node no,ComplexObject obj){ if (no==null) return; NamedNodeMap attrs = no.getAttributes(); for (int i=0;i<attrs.getLength();i++){ String name=attrs.item(i).getNodeName(); String val=attrs.item(i).getNodeValue(); if (name.compareTo("name")==0) obj.setValue(val); obj.setAttributeValue(name,val); } } /** Load the data from the selected path */ public void load(){ if(parser==null){ parser = new DOMParser(); } try { parser.parse(path); doc = parser.getDocument(); } catch (Exception e) { e.getMessage(); } nodes.clear(); // Only one Type Node no=doc.getElementsByTagName(EbeDocument.getClassType().name).item(0); readNode(no,this); // Check for Completions NodeList completionNodes = doc.getElementsByTagName(Completion.getClassType().name); for (int i = 0; i < completionNodes.getLength(); i++){ Node coNo=completionNodes.item(i); Completion coObj = new Completion(); readNode(coNo,coObj); this.putNode(coObj); } NodeList errorNodes = doc.getElementsByTagName(Error.getClassType().name); for (int i = 0; i < errorNodes.getLength(); i++){ Node erNo=errorNodes.item(i); Error erObj = new Error(); readNode(erNo,erObj); Node meNo = erNo.getFirstChild(); while (meNo != null) { if (meNo.getNodeName().matches("Member")){ Member meObj=new Member(); readNode(meNo,meObj); erObj.putMember(meObj); } meNo = meNo.getNextSibling(); } this.putNode(erObj); } } /** Fill a DOM Element from a ComplexObject (for save) * @param obj the ComplexObject with attributes * @param toFill the DOM element to fill*/ private void fillAttributes(ComplexObject obj,Element toFill){ for (String attr: obj.getAttributes().keySet()){ toFill.setAttribute(attr,obj.getAttributeValue(attr)); } } /** Save the data to the selected path * @throws IOException * @throws FileNotFoundException */ public void save() throws FileNotFoundException, IOException{ Document docFile=new DocumentImpl(); Element typeElement=docFile.createElement(EbeDocument.getClassType().name); fillAttributes(this,typeElement); for (ComplexObject node: nodes.values()){ Element nodeElement; if (node instanceof Error) nodeElement=docFile.createElement("ErrorCode"); else nodeElement=docFile.createElement("Code"); fillAttributes(node,nodeElement); if (node instanceof Error){ Error err=(Error)node; for (ComplexObject memb: err.getMembers().values()){ Element membElement=docFile.createElement("Member"); fillAttributes(memb,membElement); nodeElement.appendChild(membElement); } } typeElement.appendChild(nodeElement); } docFile.appendChild(typeElement); saveXmlDocument(docFile,getPath()); } /** Save the DOM document into the name path * @param docu The DOM document * @param name the filename path*/ private void saveXmlDocument(Document docu,String name) throws FileNotFoundException, java.io.IOException{ OutputFormat outFormat = new OutputFormat(Method.XML,null,true); outFormat.setEncoding("UTF-8"); outFormat.setVersion("1.0"); FileOutputStream out = new FileOutputStream(name); XMLSerializer xmlSerializer=new XMLSerializer( new PrintWriter(out), outFormat); xmlSerializer.serialize(docu); out.close(); } /** Add a node (completion/error) to the document * @param obj the Object to add*/ public void putNode(ComplexObject obj){ nodes.put(obj.getValue(),obj); } /** Get the nodes (completion/error) TreeMap * @return the nodes TreeMap */ public TreeMap<String,ComplexObject> getNodes(){ return(nodes); } /** Get a node by name * @param name a name to get the node * @return a ComplexNode */ public ComplexObject getNode(String name){ return(nodes.get(name)); } /** Set the basic document info * @param _prefix prefix (like alma) * @param xsi xsi info * @param xsiLocation the xsi location * @param name the document name */ public void setDocumentInfo(String _prefix,String xsi,String xsiNamespace, String xsiLocation, String name){ setAttributeValue("xsi:schemaLocation",xsiNamespace + " " + xsiLocation); setAttributeValue("xmlns",xsiNamespace); setAttributeValue("xmlns:xsi",xsi); setAttributeValue("_prefix",_prefix); setAttributeValue("name",name); } /** Set the basic document info defaults * @param name the document name */ public void setDocumentInfo(String name){ setDocumentInfo("alma","http://www.w3.org/2001/XMLSchema-instance","Alma/ACSError","ACSError.xsd",name); } }