|
What this is
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.schema2beans;
import java.util.*;
import java.io.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
*
*
*/
public class GraphManager extends Object {
public static interface Writer {
public void write(OutputStream out, Document doc);
}
public static interface Factory {
public org.w3c.dom.Document createDocument(InputStream in,
boolean validate);
}
Document document = null;
NodeFactory factory = null;
HashMap bindingsMap = new HashMap();
BaseBean root;
private boolean writeCData = false;
// When set to null (default), use XMLDocument instead
private Factory docFactory;
private Writer docWriter;
private String docTypePublic;
private String docTypeSystem;
//
// The key is the input stream. This is how we can get the
// factory/writer when we are asked to build a Dom graph.
//
static Map factoryMap = Collections.synchronizedMap(new HashMap(2));
static Map writerMap = Collections.synchronizedMap(new HashMap(2));
public GraphManager(BaseBean root) {
this.root = root;
}
/**
* Associate a factory to a stream
*/
public static void setFactory(InputStream in,
GraphManager.Factory factory) throws Schema2BeansException {
setFactory(in, factory, null);
}
/**
* Set an external factory to use instead of the default one
*/
public static void setFactory(InputStream in, GraphManager.Factory factory,
GraphManager.Writer writer) throws Schema2BeansException {
if (in == null)
throw new Schema2BeansException(Common.getMessage(
"InputStreamCantBeNull_msg"));
if (factory != null)
GraphManager.factoryMap.put(in, factory);
else
GraphManager.factoryMap.remove(in);
if (writer != null)
GraphManager.writerMap.put(in, writer);
else
GraphManager.writerMap.remove(in);
}
/**
* Set an external writer to use instead of the default one
*/
public void setWriter(GraphManager.Writer writer) {
this.docWriter = writer;
}
public void setWriteCData(boolean value) {
writeCData = value;
}
public static Node createRootElementNode(String name) throws Schema2BeansRuntimeException {
String s = "\n" +// NOI18N
"<" + name + "/>"; // NOI18N
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
Document doc = GraphManager.createXmlDocument(in, false);
NodeList children = doc.getChildNodes();
int length = children.getLength();
for (int i = 0; i < length; ++i) {
Node node = children.item(i);
if (node instanceof DocumentType) {
//System.out.println("Found DocumentType where there should be none.");
doc.removeChild(node);
--length;
}
}
return doc;
}
//
// Document created for this GraphManager. Called by the generated bean.
//
public void setXmlDocument(Node doc) throws Schema2BeansRuntimeException {
if (doc instanceof Document) {
this.document = (Document)doc;
this.setNodeFactory((Document)doc);
//
// The factory/writer should know about the doc now
// and no more about the original InputStream.
// (if the user specified a factory/writer)
//
Object o = GraphManager.factoryMap.get(doc);
if (o != null) {
this.docFactory = (GraphManager.Factory)o;
GraphManager.factoryMap.remove(doc);
}
o = GraphManager.writerMap.get(doc);
if (o != null) {
this.docWriter = (GraphManager.Writer)o;
GraphManager.writerMap.remove(doc);
}
}
else
throw new Schema2BeansRuntimeException(Common.getMessage(
"CantFindFactory_msg"));
}
/**
* This returns the DOM Document object, root
* of the current DOM graph. Operations that cause structural
* modifications to the DOM graph are not allowed. Indeed,
* modifying the DOM graph directly would cause the bean graph
* and its internal representation to be out of sync.
*/
public Document getXmlDocument() {
return this.document;
}
public void setDoctype(String publicId, String systemId) {
//System.out.println("GraphManager.setDoctype: publicId="+publicId+" systemId="+systemId);
this.docTypePublic = publicId;
this.docTypeSystem = systemId;
}
/**
* Parse the DOM tree until the element named 'name' is found.
* Return the node of the name or null if not found.
* This method is used by the root bean generated class to get
* the root element of the DOM tree and start building the
* bean graph from here.
*/
public static Node getElementNode(String name, Node doc) {
Node n;
for (n = doc.getFirstChild(); n != null; n = n.getNextSibling()) {
if (n.getNodeType() == Node.ELEMENT_NODE
&& n.getNodeName().equals(name)) {
break;
}
}
return n;
}
/**
* This method is called by the createRoot() method of the root bean
* (part of the BaseBean class). The doc might not be available
* at the time of this call. In such a case, the method
* completeRootBinding is called afterwards with the doc value to complete
* the setup of the root.
*
* This makes sure that the root element of the object bindings
* between the beans and the DOM Nodes is created, before that the
* recursing creation of the graph begins.
*/
public void createRootBinding(BaseBean beanRoot, BeanProp prop, Node doc) throws Schema2BeansException {
prop.registerDomNode(doc, null, beanRoot);
if (doc != null)
this.bindingsMap.put(doc, beanRoot.binding);
}
public void completeRootBinding(BaseBean beanRoot, Node doc) {
this.bindingsMap.put(doc, beanRoot.binding);
beanRoot.binding.setNode(doc);
}
/**
* This method sets the DOM nodes factory.
*/
public void setNodeFactory(Document doc) {
this.factory = new NodeFactory(doc);
}
/**
* Return the DOM node factory
*/
public NodeFactory getNodeFactory() {
return this.factory;
}
/**
* Return the root of the bean graph
*/
public BaseBean getBeanRoot() {
return this.root;
}
/**
* OutputStream version of write()
*/
void write(OutputStream out) throws IOException, Schema2BeansException {
//
// Code specific to the DOM implementation:
//
if (this.document == null)
throw new Schema2BeansException(Common.getMessage("CantGetDocument_msg"));
if (this.docWriter != null)
this.docWriter.write(out, this.document);
else {
XMLUtil.DOMWriter domWriter = getDOMWriter();
domWriter.write(out, document);
}
}
protected void write(OutputStream out, String encoding) throws java.io.IOException {
XMLUtil.DOMWriter domWriter = getDOMWriter();
domWriter.write(out, encoding, document);
}
protected void write(java.io.Writer out) throws java.io.IOException {
XMLUtil.DOMWriter domWriter = getDOMWriter();
domWriter.setWriter(out);
domWriter.write(document);
}
protected void write(java.io.Writer out, String encoding) throws java.io.IOException {
XMLUtil.DOMWriter domWriter = getDOMWriter();
domWriter.setWriter(out);
domWriter.write(document, encoding);
}
public void write(java.io.Writer out, Node node) throws java.io.IOException, Schema2BeansException {
XMLUtil.DOMWriter domWriter = getDOMWriter();
domWriter.setWriter(out);
domWriter.write(node);
}
protected XMLUtil.DOMWriter getDOMWriter() {
XMLUtil.DOMWriter domWriter = new XMLUtil.DOMWriter();
domWriter.setDocTypePublic(docTypePublic);
domWriter.setDocTypeSystem(docTypeSystem);
domWriter.setWriteCData(writeCData);
return domWriter;
}
/**
* Take the current DOM tree and readjust whitespace so that it
* looks pretty.
*/
public void reindent(String indent) {
XMLUtil.reindent(document, indent);
}
/**
* Indent by 2 spaces for every @level.
*/
protected static void printLevel(java.io.Writer out, int level, String indent) throws java.io.IOException {
StringBuffer outBuf = new StringBuffer();
printLevel(outBuf, level, indent);
out.write(outBuf.toString());
}
protected static void printLevel(StringBuffer out, int level, String indent) {
for (int i = 0; i < level; ++i) {
out.append(indent);
}
}
protected static void printLevel(java.io.Writer out, int level, String indent, String text) throws java.io.IOException {
StringBuffer outBuf = new StringBuffer();
printLevel(outBuf, level, indent, text);
out.write(outBuf.toString());
}
protected static void printLevel(OutputStream out, int level, String indent, String text) throws java.io.IOException {
OutputStreamWriter w = new OutputStreamWriter(out);
printLevel(w, level, indent, text);
w.flush();
}
protected static void printLevel(StringBuffer out, int level,
String indent, String text) {
printLevel(out, level, indent);
out.append(text);
}
/**
* Creates a DOM document from the input stream.
*/
public static Document createXmlDocument(InputStream in, boolean validate) throws Schema2BeansRuntimeException {
return createXmlDocument(in, validate, null);
}
private static InputStream tee(InputStream in) throws IOException {
byte[] buf = new byte[4096];
ByteArrayOutputStream ba = new ByteArrayOutputStream();
int totalLength = 0;
int len;
while ((len = in.read(buf, 0, 4096)) > 0) {
ba.write(buf, 0, len);
totalLength += len;
}
System.out.println("schema2beans: in (length="+totalLength+"):");
System.out.println(ba.toString());
ByteArrayInputStream bain = new ByteArrayInputStream(ba.toByteArray());
return bain;
}
/**
* Creates a DOM document from the input stream.
*/
public static Document createXmlDocument(InputStream in, boolean validate,
EntityResolver er) throws Schema2BeansRuntimeException {
if (in == null)
throw new IllegalArgumentException("in == null"); // NOI18N
try {
if (DDLogFlags.debug) {
// Dump the contents to stdout
in = tee(in);
}
//
// Change the references to map the newly created doc
// The BaseBean instance is not created yet. The doc
// document will be used to get back the factories.
//
Object o = GraphManager.factoryMap.get(in);
if (o != null) {
GraphManager.Factory f = (GraphManager.Factory)o;
Document doc = f.createDocument(in, validate);
GraphManager.factoryMap.remove(in);
GraphManager.factoryMap.put(doc, o);
Object o2 = GraphManager.writerMap.get(in);
if (o2 != null) {
GraphManager.writerMap.remove(in);
GraphManager.writerMap.put(doc, o2);
}
return doc;
}
else {
return createXmlDocument(new InputSource(in), validate, er, null);
}
} catch (Schema2BeansException e) {
throw new Schema2BeansRuntimeException(e);
} catch (IOException e) {
throw new Schema2BeansRuntimeException(e);
}
}
public static Document createXmlDocument(InputSource in, boolean validate) throws Schema2BeansException {
return createXmlDocument(in, validate, null, null);
}
public static Document createXmlDocument(InputSource in, boolean validate,
EntityResolver er, ErrorHandler eh) throws Schema2BeansException {
if (in == null)
throw new IllegalArgumentException("in == null"); // NOI18N
if (validate == false && er == null) {
// The client is not interested in any validation, so make
// see to it that any entity resolution doesn't hit the network
er = NullEntityResolver.newInstance();
}
try {
// Build a Document using JAXP
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setValidating(validate);
DocumentBuilder db = dbf.newDocumentBuilder();
if (er != null)
db.setEntityResolver(er);
if (eh != null)
db.setErrorHandler(eh);
if (DDLogFlags.debug) {
System.out.println("createXmlDocument: validate="+validate+" dbf="+dbf+" db="+db+" er="+er);
}
return db.parse(in);
} catch (javax.xml.parsers.ParserConfigurationException e) {
throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
} catch (org.xml.sax.SAXException e) {
throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
} catch (IOException e) {
throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
}
}
/**
* This method is called by the generated beans when they are
* building themselves from a DOM tree.
* Typically, the first root bean calls this method with the
* DOM root node and the list of the properties that are expected
* under this node.
* This method parses the DOM sub-node of the node and matches their names
* with the names of the properties. When a match is found, the
* bean property object is called with the node found. If the node
* has no match in the bean properties, the node is ignored but
* the event is logged as it might reveal a problem in the bean tree
* (DTD element missing in the bean class graph).
*
*/
public void fillProperties(BeanProp[] prop, Node node) throws Schema2BeansException {
BaseBean bean;
DOMBinding binding, newBinding;
if (prop == null || node == null)
return;
if (this.bindingsMap.get(node) == null) {
throw new Schema2BeansException(Common.getMessage(
"CurrentNodeHasNoBinding_msg", new Integer(node.hashCode())));
}
// Store the property's dtdName's into a map for fast lookup,
// and be able to handle multiple properties with the same name.
Map dtdName2Prop = new HashMap(); // Map
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.