/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI 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 at gnu.org.
*/
package com.eviware.soapui.impl.wadl.inference.schema.particles;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.XmlException;
import com.eviware.soapui.impl.wadl.inference.ConflictHandler;
import com.eviware.soapui.impl.wadl.inference.schema.Context;
import com.eviware.soapui.impl.wadl.inference.schema.Particle;
import com.eviware.soapui.impl.wadl.inference.schema.Schema;
import com.eviware.soapui.impl.wadl.inference.schema.Settings;
import com.eviware.soapui.impl.wadl.inference.schema.Type;
import com.eviware.soapui.impl.wadl.inference.schema.types.TypeReferenceType;
import com.eviware.soapui.inferredSchema.ElementParticleConfig;
import com.eviware.soapui.inferredSchema.MapEntryConfig;
import com.eviware.soapui.inferredSchema.TypeConfig;
/**
* Represents an xs:element, with a name, a type, etc.
*
* @author Dain Nilsson
*/
public class ElementParticle implements Particle
{
private String name;
private Schema schema;
private Type type;
private Map<String, String> attributes;
public ElementParticle( Schema schema, String name )
{
this.schema = schema;
this.name = name;
type = Type.Factory.newType( schema );
attributes = new HashMap<String, String>();
}
public ElementParticle( ElementParticleConfig xml, Schema schema )
{
this.schema = schema;
name = xml.getName();
type = Type.Factory.parse( xml.getType(), schema );
attributes = new HashMap<String, String>();
for( MapEntryConfig entry : xml.getAttributeList() )
{
attributes.put( entry.getKey(), entry.getValue() );
}
}
public ElementParticleConfig save()
{
ElementParticleConfig xml = ElementParticleConfig.Factory.newInstance();
xml.setName( name );
for( Map.Entry<String, String> entry : attributes.entrySet() )
{
MapEntryConfig mapEntry = xml.addNewAttribute();
mapEntry.setKey( entry.getKey() );
mapEntry.setValue( entry.getValue() );
}
TypeConfig xml2 = type.save();
xml.setType( xml2 );
return xml;
}
public String getAttribute( String key )
{
String value = attributes.get( key );
if( ( key.equals( "minOccurs" ) || key.equals( "maxOccurs" ) ) && value == null )
value = "1";
return value;
}
public QName getName()
{
return new QName( schema.getNamespace(), name );
}
public Type getType()
{
return type;
}
public void setAttribute( String key, String value )
{
attributes.put( key, value );
}
public void setType( Type type )
{
this.type = type;
}
public void validate( Context context ) throws XmlException
{
context.cd( name );
context.getCursor().push();
String nil = context.getCursor().getAttributeText( new QName( Settings.xsins, "nil" ) );
if( nil != null && nil.equals( "true" ) )
{
if( getAttribute( "nillable" ) == null || !getAttribute( "nillable" ).equals( "true" ) )
{
if( context.getHandler().callback( ConflictHandler.Event.MODIFICATION, ConflictHandler.Type.ELEMENT,
getName(), context.getPath(), "Non-nillable element is nil." ) )
{
setAttribute( "nillable", "true" );
}
else
throw new XmlException( "Non-nillable element is nil!" );
}
context.putAttribute( "nil", "true" );
}
Type newType = type.validate( context );
if( newType != type )
{
String problem = "Illegal content for element '" + name + "' with type '" + type.getName() + "'.";
if( type instanceof TypeReferenceType
|| context.getHandler().callback( ConflictHandler.Event.MODIFICATION, ConflictHandler.Type.ELEMENT,
getName(), context.getPath(), "Illegal content." ) )
{
type = newType;
context.getCursor().pop();
context.up();
validate( context );
return;
}
else
throw new XmlException( problem );
}
context.clearAttribute( "nil" );
context.up();
context.getCursor().pop();
}
@Override
public String toString()
{
StringBuilder s = new StringBuilder( "<" + schema.getPrefixForNamespace( Settings.xsdns ) + ":" + getPType()
+ " name=\"" + name + "\" type=\"" );
if( type.getSchema() != schema )
s.append( schema.getPrefixForNamespace( type.getSchema().getNamespace() ) + ":" );
s.append( type.getName() + "\"" );
for( Map.Entry<String, String> entry : attributes.entrySet() )
s.append( " " + entry.getKey() + "=\"" + entry.getValue() + "\"" );
s.append( "/>" );
return s.toString();
}
public Particle.ParticleType getPType()
{
return Particle.ParticleType.ELEMENT;
}
}