View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wadl.inference.schema.particles;
14  
15  import java.util.HashMap;
16  import java.util.Map;
17  
18  import javax.xml.namespace.QName;
19  
20  import org.apache.xmlbeans.XmlException;
21  
22  import com.eviware.soapui.impl.wadl.inference.ConflictHandler;
23  import com.eviware.soapui.impl.wadl.inference.schema.Context;
24  import com.eviware.soapui.impl.wadl.inference.schema.Particle;
25  import com.eviware.soapui.impl.wadl.inference.schema.Schema;
26  import com.eviware.soapui.impl.wadl.inference.schema.Settings;
27  import com.eviware.soapui.impl.wadl.inference.schema.Type;
28  import com.eviware.soapui.impl.wadl.inference.schema.types.TypeReferenceType;
29  import com.eviware.soapui.inferredSchema.ElementParticleConfig;
30  import com.eviware.soapui.inferredSchema.MapEntryConfig;
31  import com.eviware.soapui.inferredSchema.TypeConfig;
32  
33  /***
34   * Represents an xs:element, with a name, a type, etc.
35   * 
36   * @author Dain Nilsson
37   */
38  public class ElementParticle implements Particle
39  {
40  	private String name;
41  	private Schema schema;
42  	private Type type;
43  	private Map<String, String> attributes;
44  
45  	public ElementParticle( Schema schema, String name )
46  	{
47  		this.schema = schema;
48  		this.name = name;
49  		type = Type.Factory.newType( schema );
50  		attributes = new HashMap<String, String>();
51  	}
52  
53  	public ElementParticle( ElementParticleConfig xml, Schema schema )
54  	{
55  		this.schema = schema;
56  		name = xml.getName();
57  		type = Type.Factory.parse( xml.getType(), schema );
58  		attributes = new HashMap<String, String>();
59  		for( MapEntryConfig entry : xml.getAttributeList() )
60  		{
61  			attributes.put( entry.getKey(), entry.getValue() );
62  		}
63  	}
64  
65  	public ElementParticleConfig save()
66  	{
67  		ElementParticleConfig xml = ElementParticleConfig.Factory.newInstance();
68  		xml.setName( name );
69  		for( Map.Entry<String, String> entry : attributes.entrySet() )
70  		{
71  			MapEntryConfig mapEntry = xml.addNewAttribute();
72  			mapEntry.setKey( entry.getKey() );
73  			mapEntry.setValue( entry.getValue() );
74  		}
75  		TypeConfig xml2 = type.save();
76  		xml.setType( xml2 );
77  		return xml;
78  	}
79  
80  	public String getAttribute( String key )
81  	{
82  		String value = attributes.get( key );
83  		if( ( key.equals( "minOccurs" ) || key.equals( "maxOccurs" ) ) && value == null )
84  			value = "1";
85  		return value;
86  	}
87  
88  	public QName getName()
89  	{
90  		return new QName( schema.getNamespace(), name );
91  	}
92  
93  	public Type getType()
94  	{
95  		return type;
96  	}
97  
98  	public void setAttribute( String key, String value )
99  	{
100 		attributes.put( key, value );
101 	}
102 
103 	public void setType( Type type )
104 	{
105 		this.type = type;
106 	}
107 
108 	public void validate( Context context ) throws XmlException
109 	{
110 		context.cd( name );
111 		context.getCursor().push();
112 		String nil = context.getCursor().getAttributeText( new QName( Settings.xsins, "nil" ) );
113 		if( nil != null && nil.equals( "true" ) )
114 		{
115 			if( getAttribute( "nillable" ) == null || !getAttribute( "nillable" ).equals( "true" ) )
116 			{
117 				if( context.getHandler().callback( ConflictHandler.Event.MODIFICATION, ConflictHandler.Type.ELEMENT,
118 						getName(), context.getPath(), "Non-nillable element is nil." ) )
119 				{
120 					setAttribute( "nillable", "true" );
121 				}
122 				else
123 					throw new XmlException( "Non-nillable element is nil!" );
124 			}
125 			context.putAttribute( "nil", "true" );
126 		}
127 		Type newType = type.validate( context );
128 		if( newType != type )
129 		{
130 			String problem = "Illegal content for element '" + name + "' with type '" + type.getName() + "'.";
131 			if( type instanceof TypeReferenceType
132 					|| context.getHandler().callback( ConflictHandler.Event.MODIFICATION, ConflictHandler.Type.ELEMENT,
133 							getName(), context.getPath(), "Illegal content." ) )
134 			{
135 				type = newType;
136 				context.getCursor().pop();
137 				context.up();
138 				validate( context );
139 				return;
140 			}
141 			else
142 				throw new XmlException( problem );
143 		}
144 		context.clearAttribute( "nil" );
145 		context.up();
146 		context.getCursor().pop();
147 	}
148 
149 	@Override
150 	public String toString()
151 	{
152 		StringBuilder s = new StringBuilder( "<" + schema.getPrefixForNamespace( Settings.xsdns ) + ":" + getPType()
153 				+ " name=\"" + name + "\" type=\"" );
154 		if( type.getSchema() != schema )
155 			s.append( schema.getPrefixForNamespace( type.getSchema().getNamespace() ) + ":" );
156 		s.append( type.getName() + "\"" );
157 		for( Map.Entry<String, String> entry : attributes.entrySet() )
158 			s.append( " " + entry.getKey() + "=\"" + entry.getValue() + "\"" );
159 		s.append( "/>" );
160 		return s.toString();
161 	}
162 
163 	public Particle.ParticleType getPType()
164 	{
165 		return Particle.ParticleType.ELEMENT;
166 	}
167 
168 }