📄 xmlmapper.java
字号:
package org.apache.tomcat.util.xml;import org.apache.tomcat.util.*;import java.beans.*;import java.io.*;import java.io.IOException;import java.lang.reflect.*;import java.net.URL;import java.net.URLConnection;import java.util.*;import java.util.StringTokenizer;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.*;import org.xml.sax.helpers.*;/** * SAX Handler - it will read the XML and construct java objects * * @author costin@dnt.ro */public class XmlMapper extends HandlerBase implements SaxContext { Locator locator; /** * The URLs of DTDs that have been registered, keyed by the public * identifier that corresponds. */ private Hashtable fileDTDs = new Hashtable(); private Hashtable resDTDs = new Hashtable(); // Stack of elements Stack oStack=new Stack(); Object root; Object attributeStack[]; String tagStack[]; int oSp; int sp; String body; int debug=0; boolean validating=false; public XmlMapper() { attributeStack = new Object[100]; // depth of the xml doc tagStack = new String[100]; initDefaultRules(); } public void setDocumentLocator (Locator locator) { if( debug>0 ) log("Set locator : " + locator); this.locator = locator; } public void startDocument () throws SAXException { sp = 0; } public void endDocument () throws SAXException { if (sp != 0) { System.out.println("The XML document is probably broken. " + sp); } } public void startElement (String tag, AttributeList attributes) throws SAXException { try { // if( debug>0) log(sp + "<" + tag + " " + attributes + ">"); attributeStack[sp]=attributes; tagStack[sp]=tag; sp++; matchStart( this); body=""; } catch (Exception ex) { // do not ignore messages, caller should handle it throw new SAXException( positionToString(), ex ); } } private String positionToString() { StringBuffer sb=new StringBuffer(); if( locator!=null ) sb.append("Line ").append(locator.getLineNumber()).append(" "); sb.append("/"); for( int i=0; i< sp ; i++ ) sb.append( tagStack[i] ).append( "/" ); sb.append(" "); AttributeList attributes=(AttributeList) attributeStack[sp-1]; if( attributes!=null) for (int i = 0; i < attributes.getLength (); i++) { sb.append(attributes.getName(i)).append( "=" ).append(attributes.getValue(i)); sb.append(" "); } return sb.toString(); } public void endElement (String tag) throws SAXException { try { // Find a match for the current tag in the context matchEnd( this); if( sp > 1 ) { tagStack[sp] = null; attributeStack[sp]=null; } sp--; } catch (Exception ex) { // do not ignore messages, caller should handle it throw new SAXException( positionToString(), ex ); } } public void characters (char buf [], int offset, int len) throws SAXException { body=body+ new String(buf, offset, len ); } public void ignorableWhitespace (char buf [], int offset, int len) throws SAXException { } public void processingInstruction (String name, String instruction) throws SAXException { } // -------------------- Context -------------------- // provide access to the current stack and XML elements. // -------------------- Context -------------------- public AttributeList getAttributeList( int pos ) { return (AttributeList)attributeStack[pos]; } public int getTagCount() { return sp; } public String getTag( int pos ) { return tagStack[pos]; } public String getBody() { return body; } public Stack getObjectStack() { return oStack; } public Object getRoot() { return root; } public void setRoot(Object o) { root=o; } // -------------------- Utils -------------------- // Debug ( to be replaced with the real thing ) public void setDebug( int level ) { if(level!=0) log( "Debug level: " + level ); debug=level; } public int getDebug() { return debug; } public void setValidating( boolean validating ) { if (debug >= 1) log("Validating = " + validating); this.validating = validating; } public boolean getValidating() { return (this.validating); } public void log(String msg) { // log is for debug only, it should't be enabled for anything else // ( no dependency on Logger or any external tomcat package ) System.out.println("XmlMapper: " + msg); } /** read an XML file, construct and return the object hierarchy */ public Object readXml(File xmlFile, Object root) throws Exception { if(root!=null) { Stack st=this.getObjectStack(); this.root=root; st.push( root ); } try { SAXParser parser=null; SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(false); factory.setValidating(validating); parser = factory.newSAXParser(); parser.parse(xmlFile, this); return root; // assume the stack is in the right position. // or throw an exception is more than one element is on the stack } catch (IOException ioe) { ioe.printStackTrace(); String msg = "Can't open config file: " + xmlFile + " due to: " + ioe; throw new Exception(msg); } catch (SAXException se) { System.out.println("ERROR reading " + xmlFile); System.out.println("At " + se.getMessage()); // se.printStackTrace(); System.out.println(); Exception ex1=se.getException(); if( ex1 != null ) throw ex1;// xerces bug else throw se; } } /** read an XML input stream, construct and return the object hierarchy */ public Object readXml(InputStream xmlFile, Object root) throws Exception { if(root!=null) { Stack st=this.getObjectStack(); this.root=root; st.push( root ); } SAXParser parser=null; try { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(false); factory.setValidating(validating); parser = factory.newSAXParser(); parser.parse(xmlFile, this); return root; // assume the stack is in the right position. // or throw an exception is more than one element is on the stack } catch (IOException ioe) { String msg = "Can't open config file: " + xmlFile + " due to: " + ioe; throw new Exception(msg); } catch (SAXException se) { System.out.println("ERROR reading " + xmlFile); System.out.println("At " + se.getMessage()); // se.printStackTrace(); System.out.println(); Exception ex1=se.getException(); throw ex1; } } /** * Register the specified DTD with a local file. * This must be called prior to the first call to <code>readXml()</code>. * * @param publicId Public identifier of the DTD to be resolved * @param dtdFile The local file name to use for reading this DTD */ public void registerDTDFile(String publicId, String dtdFile) { fileDTDs.put(publicId, dtdFile); } /** * Register the specified DTD to map to a resource in the classpath * This must be called prior to the first call to <code>readXml()</code>. * * @param publicId Public identifier of the DTD to be resolved * @param dtdRes local resource name, to be used with getResource() */ public void registerDTDRes(String publicId, String dtdRes) { resDTDs.put(publicId, dtdRes); } class Rule { XmlMatch match; XmlAction action; Rule( XmlMatch match, XmlAction action ) { this.match=match; this.action=action; } } Rule rules[]=new Rule[100]; Rule matching[]=new Rule[100]; int ruleCount=0; /** */ private void initDefaultRules() { // One-time actions, in line addRule( "xmlmapper:debug", new XmlAction() { public void start(SaxContext ctx) { int top=ctx.getTagCount()-1; AttributeList attributes = ctx.getAttributeList( top ); String levelS=attributes.getValue("level"); XmlMapper mapper=(XmlMapper)ctx; if( levelS!=null) mapper.setDebug( new Integer(levelS).intValue()); } } ); // ant-like addRule( "xmlmapper:taskdef", new XmlAction() { public void start(SaxContext ctx) { XmlMapper mapper=(XmlMapper)ctx; int top=ctx.getTagCount()-1; AttributeList attributes = ctx.getAttributeList( top ); String match=attributes.getValue("match"); if(match==null) return; //log String obj=attributes.getValue("object-create"); String objA=attributes.getValue("object-create-attrib"); if( obj!=null || objA!=null) mapper.addRule( match, new ObjectCreate( obj, objA)); obj=attributes.getValue("set-properties"); if( obj!=null) mapper.addRule( match, new SetProperties()); obj=attributes.getValue("set-parent"); if( obj!=null) mapper.addRule( match, new SetParent(obj)); obj=attributes.getValue("add-child"); objA=attributes.getValue("child-type"); if( obj!=null) mapper.addRule( match, new AddChild(obj, objA)); // Custom actions obj=attributes.getValue("action"); if( obj!=null) { try { Class c=Class.forName( obj ); Object o=c.newInstance(); mapper.addRule( match, (XmlAction)o); } catch( Exception ex ) { System.out.println("Can't add action " + obj); } } } } ); } public void addRule( String path, XmlAction action ) { rules[ruleCount]=new Rule( new PathMatch( path ) , action); ruleCount++; } private int match( SaxContext ctx, Rule matching[] ) { int matchCount=0; for( int i=0; i< ruleCount; i++ ) { if( rules[i].match.match( ctx ) && rules[i].action != null ) { matching[matchCount]=rules[i]; matchCount++; } } return matchCount; } void matchStart(SaxContext ctx ) throws Exception { int matchCount=match( ctx, matching ); for ( int i=0; i< matchCount; i++ ) { matching[i].action.start( ctx ); } } void matchEnd(SaxContext ctx ) throws Exception { int matchCount=match( ctx, matching ); for ( int i=0; i< matchCount; i++ ) matching[i].action.end( ctx ); for ( int i=0; i< matchCount; i++ ) matching[i].action.cleanup( ctx ); } /** * Resolve the requested external entity, replacing it by an internal * DTD if one has been registered. * * @param publicId Public identifier of the entity being referenced * @param systemId System identifier of the entity being referenced * * @exception SAXException if a parsing error occurs */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException { String dtd = (String) fileDTDs.get(publicId); if( dtd != null ) { File dtdF=new File( dtd ); if( dtdF.exists() ) try { return new InputSource(new FileInputStream(dtdF)); } catch( FileNotFoundException ex ) { } // else continue } dtd = (String) resDTDs.get( publicId ); if( dtd != null ) { InputStream is = this.getClass().getResourceAsStream( dtd ); if( is!= null ) return new InputSource(is); System.out.println("XXX resource not found !!! " + dtd); System.out.println(this.getClass().getClassLoader().getClass().getName()); } log("Can't find resource for entity: " + publicId + " --> " + systemId + " \"" + dtd +"\""); return null; } public void notationDecl (String name, String publicId, String systemId) { System.out.println("Notation: " + name + " " + publicId + " " + systemId); } public void unparsedEntityDecl (String name, String publicId, String systemId, String notationName) { System.out.println("Unparsed: " + name + " " + publicId + " " + systemId + " " + notationName); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -