/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2006,
* @author mark.little@jboss.com
*/
/*
* Copyright (c) 2002, 2003, Arjuna Technologies Limited.
*
* PortReferenceHelper.java
*/
package org.jboss.internal.soa.esb.addressing.helpers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.jboss.internal.soa.esb.util.stax.ElementContent;
import org.jboss.internal.soa.esb.util.stax.QNameHelper;
import org.jboss.internal.soa.esb.util.stax.StreamHelper;
import org.jboss.internal.soa.esb.util.stax.TextElement;
import org.jboss.soa.esb.addressing.PortReference;
import org.jboss.soa.esb.addressing.XMLUtil;
import org.jboss.soa.esb.addressing.PortReference.Extension;
/*
* This should pack the PortReference into an ERP.
*
* It would be better if PortReference had a packToXML and unpackFromXML.
*
* This needs rewriting after the interoperability workshop!
*/
public class PortReferenceHelper
{
public static void toXML(final XMLStreamWriter out, final QName name,
final PortReference portReference)
throws XMLStreamException
{
if (XMLUtil.QNAME_TO_TAG.equals(name))
{
writeToXML(out, name, portReference) ;
}
else
{
writeXML(out, name, portReference) ;
}
}
private static void writeToXML(final XMLStreamWriter out, final QName name, final PortReference portReference)
throws XMLStreamException
{
final TextElement toElement = new TextElement(portReference.getAddress()) ;
StreamHelper.writeElement(out, name, toElement) ;
writeExtensions(out, portReference) ;
}
private static void writeXML(final XMLStreamWriter out, final QName name, final PortReference portReference)
throws XMLStreamException
{
final String origURI = StreamHelper.writeStartElement(out, name) ;
final TextElement addressElement = new TextElement(portReference.getAddress()) ;
StreamHelper.writeElement(out, XMLUtil.QNAME_ADDRESS_TAG, addressElement) ;
if (portReference.getAllExtensions().size() > 0)
{
final String origReferenceURI = StreamHelper.writeStartElement(out, XMLUtil.QNAME_REFERENCE_PROPERTIES_TAG) ;
writeExtensions(out, portReference) ;
StreamHelper.writeEndElement(out, XMLUtil.QNAME_REFERENCE_PROPERTIES_TAG.getPrefix(), origReferenceURI) ;
}
StreamHelper.writeEndElement(out, name.getPrefix(), origURI) ;
}
private static void writeExtensions(final XMLStreamWriter out, final PortReference portReference)
throws XMLStreamException
{
for(Extension extension: portReference.getAllExtensions())
{
writeExtension(out, extension) ;
}
}
private static void writeExtension(final XMLStreamWriter out, final Extension extension)
throws XMLStreamException
{
final String uri = QNameHelper.getNormalisedValue(extension.getURI()) ;
final String prefix = QNameHelper.getNormalisedValue(extension.getPrefix()) ;
final QName name = new QName(uri, extension.getTag(), prefix) ;
final String origURI = StreamHelper.writeStartElement(out, name) ;
final HashMap attributes = extension.getAttributes() ;
if (attributes != null)
{
final Iterator entryIter = attributes.entrySet().iterator() ;
while(entryIter.hasNext())
{
final Entry entry = (Entry)entryIter.next() ;
final ArjunaName arjunaName = (ArjunaName)entry.getKey() ;
final String value = (String)entry.getValue() ;
final String attributeURI = QNameHelper.getNormalisedValue(arjunaName.getURI()) ;
final String attributePrefix = QNameHelper.getNormalisedValue(arjunaName.getPrefix()) ;
final QName attributeName = new QName(attributeURI, arjunaName.getLocalName(), attributePrefix) ;
StreamHelper.writeAttribute(out, attributeName, value) ;
}
}
final TextElement value = new TextElement(extension.getValue()) ;
value.writeContent(out) ;
StreamHelper.writeEndElement(out, name.getPrefix(), origURI) ;
final List children = extension.getChildren() ;
if (children != null)
{
final Iterator childIter = extension.getChildren().iterator() ;
while(childIter.hasNext())
{
writeExtension(out, (Extension)childIter.next()) ;
}
}
}
/** **************************** */
public static PortReference fromXML(final XMLStreamReader in)
throws XMLStreamException
{
final boolean toField = XMLUtil.QNAME_TO_TAG.equals(in.getName()) ;
if (toField)
{
return readToXML(in) ;
}
else
{
return readXML(in) ;
}
}
private static PortReference readToXML(final XMLStreamReader in)
throws XMLStreamException
{
final PortReference portReference = new PortReference() ;
final TextElement toElement = new TextElement(in) ;
portReference.setAddress(toElement.getText()) ;
return portReference ;
}
private static PortReference readXML(final XMLStreamReader in)
throws XMLStreamException
{
final PortReferenceImpl portReferenceImpl = new PortReferenceImpl(in) ;
return portReferenceImpl.getPortReference() ;
}
private static class PortReferenceImpl extends ElementContent
{
private final PortReference portReference = new PortReference() ;
PortReferenceImpl(final XMLStreamReader in)
throws XMLStreamException
{
parse(in) ;
}
PortReference getPortReference()
{
return portReference ;
}
@Override
protected void putElement(XMLStreamReader in, QName elementName)
throws XMLStreamException
{
if (XMLUtil.QNAME_ADDRESS_TAG.equals(elementName))
{
final TextElement address = new TextElement(in) ;
portReference.setAddress(address.getText()) ;
}
else if (XMLUtil.QNAME_REFERENCE_PROPERTIES_TAG.equals(elementName))
{
final ReferencePropertiesImpl referenceProperties = new ReferencePropertiesImpl(in) ;
portReference.addExtensions(referenceProperties.getExtensions()) ;
}
else
{
throw new XMLStreamException("Unrecognised element name: " + elementName) ;
}
}
}
private static class ReferencePropertiesImpl extends ElementContent
{
private List<Extension> extensions = new ArrayList<Extension>() ;
ReferencePropertiesImpl(final XMLStreamReader in)
throws XMLStreamException
{
parse(in) ;
}
List<Extension> getExtensions()
{
return extensions ;
}
@Override
protected void putElement(XMLStreamReader in, QName elementName)
throws XMLStreamException
{
final ExtensionImpl extension = new ExtensionImpl(in) ;
extensions.add(extension.getExtension()) ;
}
}
private static class ExtensionImpl extends ElementContent
{
private final List<Extension> extensions = new ArrayList<Extension>() ;
private final HashMap<ArjunaName, String> attributes = new HashMap<ArjunaName, String>() ;
private final Extension extension ;
private String value ;
ExtensionImpl(final XMLStreamReader in)
throws XMLStreamException
{
final QName name = in.getName() ;
parse(in) ;
extension = new Extension(name.getLocalPart(), name.getPrefix(),
name.getNamespaceURI(), value) ;
}
Extension getExtension()
{
return extension ;
}
@Override
protected void putAttribute(XMLStreamReader in, QName attributeName,
String attributeValue) throws XMLStreamException
{
final ArjunaName name = new ArjunaName(attributeName.getNamespaceURI(),
attributeName.getPrefix(), attributeName.getLocalPart()) ;
attributes.put(name, attributeValue) ;
}
@Override
protected void putValue(XMLStreamReader in, String value)
throws XMLStreamException
{
this.value = value ;
}
@Override
protected void putElement(XMLStreamReader in, QName elementName)
throws XMLStreamException
{
final ExtensionImpl extension = new ExtensionImpl(in) ;
extensions.add(extension.getExtension()) ;
}
}
private static class ArjunaName
{
/**
* The uri.
*/
private final String uri;
/**
* The prefix.
*/
private final String prefix;
/**
* The local name.
*/
private final String localName;
/**
* Construct the name.
*
* @param uri
* The uri.
* @param prefix
* The prefix.
* @param localName
* The local name.
*/
public ArjunaName(final String uri, final String prefix,
final String localName)
{
this.uri = uri;
this.prefix = prefix;
this.localName = localName;
}
/**
* Get the uri.
*
* @return the uri.
*/
public String getURI()
{
return uri;
}
/**
* Get the prefix.
*
* @return the prefix.
*/
public String getPrefix()
{
return prefix;
}
/**
* Get the local name.
*
* @return the local name.
*/
public String getLocalName()
{
return localName;
}
/**
* Get the qualified name.
*
* @return the qualified name.
*/
public String getQualifiedName()
{
return (prefix == null ? localName : prefix + ":" + localName);
}
}
}