/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY 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 along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.aop.junit;
import java.util.Collection;
import java.util.Iterator;
import javax.xml.XMLConstants;
import org.jboss.xb.binding.sunday.unmarshalling.AllBinding;
import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
import org.jboss.xb.binding.sunday.unmarshalling.SequenceBinding;
import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
/**
* SchemaPrinter.
*
* TODO finish this off properly
* @author <a href="ales.justin@jboss.com">Ales Justin</a>
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision: 1.1 $
*/
public class SchemaPrinter
{
@SuppressWarnings("unchecked")
public static String printSchema(SchemaBinding schemaBinding)
{
String nsURI = schemaBinding.getNamespaces().iterator().next();
StringBuilder builder = new StringBuilder();
builder.append("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n");
if (XMLConstants.NULL_NS_URI.equals(nsURI) == false)
{
builder.append(" targetNamespace=\"").append(nsURI).append("\"\n");
builder.append(" xmlns=\"").append(nsURI).append("\"\n");
}
builder.append(">\n");
int pad=3;
Iterator<ParticleBinding> elements = schemaBinding.getElementParticles();
while (elements != null && elements.hasNext())
printElement(builder, pad, elements.next());
Iterator<TypeBinding> types = schemaBinding.getTypes();
while (types != null && types.hasNext())
printType(builder, pad, types.next());
builder.append("</xsd:schema>");
return builder.toString();
}
public static void printElement(StringBuilder builder, int pad, ParticleBinding particle)
{
ElementBinding element = (ElementBinding) particle.getTerm();
pad(builder, pad);
builder.append("<element name=\"").append(element.getQName()).append("\"");
int minOccurs = particle.getMinOccurs();
if (minOccurs != 1)
builder.append(" minOccurs=\"").append(minOccurs).append("\"");
int maxOccurs = particle.getMaxOccurs();
if (maxOccurs != 1)
{
builder.append(" maxOccurs=\"");
if (maxOccurs == -1)
builder.append("unbounded");
else
builder.append(maxOccurs);
builder.append("\"");
}
TypeBinding type = element.getType();
if (type != null && type.getQName() != null)
builder.append(" type=\"").append(type.getQName()).append("\"");
builder.append(">");
if (type != null && type.getQName() == null)
printAnonymousType(builder, pad + 3, type);
pad(builder, pad);
builder.append("</element>");
}
public static void printAnonymousType(StringBuilder builder, int pad, TypeBinding type)
{
pad(builder, pad);
builder.append("<complexType>");
TypeBinding baseTypeBinding = type.getBaseType();
String qName;
if (baseTypeBinding != null)
qName = baseTypeBinding.getQName().toString();
else
qName = "xsd:anyType";
pad(builder, pad);
builder.append(" <restriction base=\"").append(qName).append("\">");
printTypeInfo(builder, pad+6, type);
pad(builder, pad);
builder.append(" </restriction>");
pad(builder, pad);
builder.append("</complexType>");
}
public static void printType(StringBuilder builder, int pad, TypeBinding type)
{
if (type.isSimple())
printSimpleType(builder, pad, type);
else
printComplexType(builder, pad, type);
}
public static void printSimpleType(StringBuilder builder, int pad, TypeBinding type)
{
pad(builder, pad);
builder.append("<simpleType name=\"").append(type.getQName()).append("\"");
TypeBinding baseTypeBinding = type.getBaseType();
String qName = null;
if (baseTypeBinding != null)
qName = baseTypeBinding.getQName().toString();
else
qName = "xsd:anySimpleType";
builder.append(" base=\"").append(qName).append("\">");
printTypeInfo(builder, pad+3, type);
pad(builder, pad);
builder.append("</simpleType>");
}
public static void printComplexType(StringBuilder builder, int pad, TypeBinding type)
{
pad(builder, pad);
builder.append("<complexType name=\"").append(type.getQName()).append("\"");
TypeBinding baseTypeBinding = type.getBaseType();
String qName = null;
if (baseTypeBinding != null)
qName = baseTypeBinding.getQName().toString();
else
qName = "xsd:anyType";
builder.append(" base=\"").append(qName).append("\">");
printTypeInfo(builder, pad+3, type);
pad(builder, pad);
builder.append("</complexType>");
}
@SuppressWarnings("unchecked")
public static void printTypeInfo(StringBuilder builder, int pad, TypeBinding type)
{
ParticleBinding particle = type.getParticle();
if (particle != null)
{
printParticle(builder, pad, particle);
}
Collection<AttributeBinding> attributes = type.getAttributes();
if (attributes != null)
{
for (AttributeBinding attribute : attributes)
{
printAttribute(builder, pad, attribute);
}
}
}
public static void printParticle(StringBuilder builder, int pad, ParticleBinding particle)
{
TermBinding term = particle.getTerm();
if (term instanceof ElementBinding)
printElement(builder, pad, particle);
else if (term instanceof WildcardBinding)
printWildcard(builder, pad, particle);
else if (term instanceof SequenceBinding)
printModel(builder, pad, particle, "sequence");
else if (term instanceof AllBinding)
printModel(builder, pad, particle, "all");
else if (term instanceof ChoiceBinding)
printModel(builder, pad, particle, "choice");
}
@SuppressWarnings("unchecked")
public static void printModel(StringBuilder builder, int pad, ParticleBinding particle, String prefix)
{
pad(builder, pad);
builder.append("<").append(prefix);
int minOccurs = particle.getMinOccurs();
if (minOccurs != 1)
builder.append(" minOccurs=\"").append(minOccurs).append("\"");
int maxOccurs = particle.getMaxOccurs();
if (maxOccurs != 1)
{
builder.append(" maxOccurs=\"");
if (maxOccurs == -1)
builder.append("unbounded");
else
builder.append(maxOccurs);
builder.append("\"");
}
builder.append(">");
ModelGroupBinding model = (ModelGroupBinding) particle.getTerm();
Collection<ParticleBinding> particles = model.getParticles();
boolean newLine = true;
if (particles != null)
{
for (ParticleBinding component : particles)
printParticle(builder, pad+3, component);
}
else
{
newLine = false;
}
pad(builder, pad, newLine);
builder.append("</").append(prefix).append(">");
}
public static void printWildcard(StringBuilder builder, int pad, ParticleBinding particle)
{
pad(builder, pad);
builder.append("<any");
int minOccurs = particle.getMinOccurs();
if (minOccurs != 1)
builder.append(" minOccurs=\"").append(minOccurs).append("\"");
int maxOccurs = particle.getMaxOccurs();
if (maxOccurs != 1)
{
builder.append(" maxOccurs=\"");
if (maxOccurs == -1)
builder.append("unbounded");
else
builder.append(maxOccurs);
builder.append("\"");
}
builder.append("/>");
}
public static void printAttribute(StringBuilder builder, int pad, AttributeBinding attribute)
{
pad(builder, pad);
TypeBinding typeBinding = attribute.getType();
String qName = null;
if (typeBinding != null && typeBinding.getQName() != null)
qName = typeBinding.getQName().toString();
else
qName = "CDATA";
builder.append("<attribute name=\"").append(attribute.getQName().getLocalPart()).append("\"");
builder.append(" type=\"").append(qName).append("\"");
if (attribute.getRequired() == false)
builder.append(" optional=\"true\"/>");
}
public static void pad(StringBuilder builder, int pad)
{
pad(builder, pad, true);
}
public static void pad(StringBuilder builder, int pad, boolean newLine)
{
if (newLine)
builder.append("\n");
for (int i = 0; i < pad; ++ i)
builder.append(' ');
}
}