All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.xml.writer.Writer Maven / Gradle / Ivy

Go to download

Jadex XML is an XML data binding framework for Java and also for other representations. The main idea of Jadex XML is that neither the XML-Schema on the one side nor the Java classes on the other side should define other binding. Instead, a separate mapping between both is used as a mediation. This allows designing the XML representation independent of the Java side but still being able to connect both as desired. This idea was first put forward by the JiBX data binding framework. Jadex XML pushes it further by combining it with the configuration by exception principle. The framework can detect obvious correspondences between both sides automatically and only needs configuration information when translations are necessary. The configuration information is currently specified directly in form of Java configuration classes.

There is a newer version: 4.0.267
Show newest version
package jadex.xml.writer;

import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

import jadex.commons.collection.Tree;
import jadex.commons.collection.TreeNode;
import jadex.xml.IPreProcessor;
import jadex.xml.SXML;
import jadex.xml.StackElement;
import jadex.xml.TypeInfo;
import jadex.xml.stax.QName;

/**
 *  XML writer for conversion of objects to XML.
 */
public class Writer extends AWriter
{
	//-------- static part --------
	
	
	/** The xml output factory. */
	protected static final XMLOutputFactory	FACTORY = XMLOutputFactory.newInstance();
//	factory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE);
	
	//-------- attributes --------
	
	/** Control flag for generating ids. */
	protected boolean genids;	
	
	/** Control flag for generating indention. */
	protected boolean indent;
	
	/** Control flag for generating newlines. */
	protected boolean newline;
	
	//-------- constructors --------

	/**
	 *  Create a new reader (with genids=true and indent=true).
	 *  @param readerhandler The handler.
	 */
	public Writer()
	{
		this(true);
	}
	
	/**
	 *  Create a new reader (with genids=true and indent=true).
	 *  @param readerhandler The handler.
	 */
	public Writer(boolean genids)
	{
		this(genids, true, true);
	}
	
	/**
	 *  Create a new reader.
	 *  @param readerhandler The handler.
	 */
	public Writer(boolean genids, boolean indent, boolean newline)
	{
		this.genids = genids;
		this.indent = indent;
		this.newline = newline;
	}
	
	//-------- methods --------
	
	/**
	 *  Write the properties to an xml.
	 *  @param input The input stream.
	 *  @param classloader The classloader.
	 * 	@param context The context.
 	 */
	public void write(IObjectWriterHandler handler, Object object, OutputStream out, ClassLoader classloader, final Object context) throws Exception
	{
		write(handler, object, SXML.DEFAULT_ENCODING, out, classloader, context);
	}
		
	/**
	 *  Write the properties to an xml.
	 *  @param input The input stream.
	 *  @param classloader The classloader.
	 * 	@param context The context.
 	 */
	public void write(IObjectWriterHandler handler, Object object, String encoding, OutputStream out, ClassLoader classloader, final Object context) throws Exception
	{
		XMLStreamWriter	writer;
		synchronized(FACTORY)
		{
			writer	= FACTORY.createXMLStreamWriter(out, encoding);
		}
		
		if(encoding!=null)
			writer.writeStartDocument(encoding, "1.0"); 
		writeNewline(writer);
		
		WriteContextDesktop wc = new WriteContextDesktop(handler, writer, context, object, classloader);
		writeObject(wc, object, null);
		writer.writeEndDocument();
		writer.close();
	}
	
	/**
	 *  Write an object to xml.
	 *  
	 *  Note:
	 *  Must have tag parameter to support writing an object using an arbitrary tag.
	 *  Cannot write tag in beforehand, because it must be written in one pass. 
	 */
	protected void writeObject(WriteContextDesktop wc, Object object, QName tag) throws Exception
	{
		XMLStreamWriter writer = getWriter(wc);
		List stack = wc.getStack();
		
		// Special case null
		if(object==null)
		{
//			writeStartObject(writer, tag==null? SXML.NULL: tag, stack.size());
			writeStartObject(writer, SXML.NULL, stack.size());
			writeEndObject(writer, stack.size());
			return;
		}
		
//		if(tagname!=null)
//			System.out.println("tagname: "+tagname);
//		if(object.getClass().getName().indexOf("ComponentIdentifier")!=-1)
//			System.out.println("cfs");
		
		TypeInfo typeinfo = wc.getHandler().getTypeInfo(object, getXMLPath(stack), wc); 
		QName[] path = new QName[0];
		
		// Preprocess object.
		IPreProcessor[] preprocs = wc.getHandler().getPreProcessors(object, typeinfo);
		if(preprocs!=null && preprocs.length>0)
		{
//			System.out.println("found: "+object);
			for(int i=0; i attrs = wi.getAttributes();
			if(attrs!=null)
			{
				for(Iterator it=attrs.keySet().iterator(); it.hasNext(); )
				{
					Object propname = it.next();
					String value = (String)attrs.get(propname);
					if(propname instanceof String)
					{
						writer.writeAttribute((String)propname, value);
					}
					else if(propname instanceof QName)
					{
						QName attrname = (QName)propname;
						// Create tag with prefix if it has a namespace but no prefix.
						if(!XMLConstants.NULL_NS_URI.equals(attrname.getNamespaceURI()) && XMLConstants.DEFAULT_NS_PREFIX.equals(attrname.getPrefix()))
						{
							attrname = wc.getHandler().getTagWithPrefix(tag, wc);
						}
						String uri = attrname.getNamespaceURI();
						String prefix = attrname.getPrefix();
						String localname = attrname.getLocalPart();
						
						if(!XMLConstants.NULL_NS_URI.equals(uri))
						{
							if(!prefix.equals(writer.getPrefix(uri)))
							{
								writer.writeAttribute(prefix, uri, localname, value);
								writer.writeNamespace(prefix, uri);
							}
							else
							{
								writer.writeAttribute(prefix, uri, localname, value);
							}
						}
						else
						{
							writer.writeAttribute(localname, value);
						}
						
						//		System.out.println("name"+tag.getLocalPart()+" prefix:"+prefix+" writerprefix:"+writer.getPrefix(uri)+" uri:"+uri);
					}
				}
			}
			
			// Content
			
			if(wi.getContent()!=null)
			{
				String content = wi.getContent();
				if(content!=null)
				{
					// Uses cdata when contains <, > or &
					// Must not use cdata when content is already cdata (nested cdata are not allowed)
					if((content.indexOf("<")!=-1 || content.indexOf(">")!=-1 || content.indexOf("&")!=-1)
						&& content.indexOf(" stack = wc.getStack();
			
		List children = node.getChildren();
		for(int i=0; i stack)
	{
		QName[] ret = new QName[stack.size()];
		for(int i=0; i