View Javadoc

1   package org.codehaus.xfire.aegis.type;
2   
3   import java.util.ArrayList;
4   import java.util.HashSet;
5   import java.util.Iterator;
6   import java.util.List;
7   import java.util.Map;
8   import java.util.Set;
9   
10  import ognl.Ognl;
11  import ognl.OgnlException;
12  
13  import org.codehaus.xfire.SOAPConstants;
14  import org.codehaus.xfire.aegis.AegisService;
15  import org.codehaus.xfire.aegis.mapping.TypeRegistry;
16  import org.codehaus.xfire.fault.XFireFault;
17  import org.dom4j.Attribute;
18  import org.dom4j.Element;
19  import org.dom4j.Namespace;
20  import org.dom4j.QName;
21  
22  /***
23   * <p>
24   * The BeanType takes child types and read/writes each of them.
25   * </p>
26   * <p>
27   * The BeanType can take its own OGNL expression and a key.  This is for when
28   * you want to take action when <i>reading</i> in an <code>Element</code>.
29   * For instance, if you specify the OGNL expression as
30   * "new com.company.Bean()" and the key as "bean" it will put a
31   * new Bean object in the context with the key "bean".
32   * </p>
33   * 
34   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
35   */
36  public class BeanType
37  	extends Type
38  {
39      private List children;
40  
41      private String key;
42      
43      public void write( Element element, Map context )
44          throws XFireFault
45      {
46          Element typeEl = element.addElement( getQName() );
47  
48          if ( getChildren() != null )
49          {
50              for ( Iterator itr = getChildren().iterator(); itr.hasNext(); )
51              {
52                  Type type = (Type) itr.next();
53                  type.write(typeEl, context);
54              }
55          }
56      }
57      
58      public void read( Element element, Map context )
59          throws XFireFault 
60      {
61          Element typeEl = element.element( getQName() );
62          
63          if ( getOgnl() != null )
64          {
65  			try
66  			{
67  				Object value = Ognl.getValue( getOgnl(), context, (Object) null );
68                  
69                  context.put( key, value );
70  			}
71  			catch (OgnlException e)
72  			{
73  				throw new XFireFault( "Couldn't process message.", e, XFireFault.SENDER );
74  			}
75  			
76          }
77          
78          if ( getChildren() != null )
79          {
80              for ( Iterator itr = getChildren().iterator(); itr.hasNext(); )
81              {
82                  Type type = (Type) itr.next();
83                  type.read(typeEl, context);
84              }
85          }
86      }
87  
88      public List getChildren()
89      {
90          return children;
91      }
92      
93      public void setChildren( List children )
94      {
95          this.children = children;
96      }
97      
98      public void addChild( Type type )
99      {
100         if ( children == null )
101             children = new ArrayList();
102         
103         children.add( type );
104     }    
105     
106 	public String getKey()
107 	{
108 		return key;
109 	}
110     
111 	public void setKey(String key)
112 	{
113 		this.key = key;
114 	}
115 
116 	public boolean isComplex()
117 	{
118 		return true;
119 	}
120     
121 	/***
122 	 * @see org.codehaus.xfire.aegis.type.Type#writeSchema(org.dom4j.Element)
123 	 */
124 	public void writeSchema(Element root)
125 	{
126         Namespace xsdNs = root.getNamespaceForURI( SOAPConstants.XSD );
127         Namespace beanNs = root.getNamespaceForURI( getSchemaType().getNamespaceURI() );
128         
129         org.dom4j.QName elementQ = new org.dom4j.QName( "element", xsdNs );
130         Element concreteEl = root.addElement( elementQ );
131         concreteEl.addAttribute("name", getName());
132         //concreteEl.addAttribute("type", beanNs.getPrefix() + ":" + getSchemaType().getName());
133         
134         org.dom4j.QName complexQ = new org.dom4j.QName("complexType", xsdNs); 
135         Element complex = concreteEl.addElement( complexQ );
136         // complex.addAttribute( "name", getName() );
137 
138         org.dom4j.QName seqQ = new org.dom4j.QName("sequence", xsdNs); 
139         Element seq = complex.addElement( seqQ );
140 
141         for ( Iterator itr = getChildren().iterator(); itr.hasNext(); )
142         {
143             Type type = (Type) itr.next();
144 
145             Element element = seq.addElement( elementQ );
146             
147             Namespace typeNS = root.getNamespaceForURI( type.getSchemaType().getNamespaceURI() );
148             if ( type.isComplex() )
149             {
150                  element.addAttribute( "ref",  typeNS.getPrefix() + ":" + type.getSchemaType().getName() );
151             }
152             else
153             {
154                 element.addAttribute( "name", type.getName() );
155                 // TODO: Add config support for nillable
156                 element.addAttribute( "nillable", "true" );
157                 element.addAttribute("type", typeNS.getPrefix() + ":" + type.getSchemaType().getName());
158             }
159         }
160 	}
161 
162 	/***
163 	 * @see org.codehaus.xfire.aegis.type.Type#configure(org.dom4j.Element)
164 	 */
165 	public void configure(Element configuration, AegisService service, TypeRegistry reg )
166 	{
167 		setName( configuration.attributeValue("name") );
168         setOgnl( configuration.attributeValue("ognl") );
169         setKey( configuration.attributeValue("key") );
170         
171         String min = configuration.attributeValue("minOccurs");
172         if (min != null)
173         	setMinOccurs(min);
174         
175         String max = configuration.attributeValue("maxOccurs");
176         if (max != null)
177         	setMaxOccurs(max);
178         
179         setQName( QName.get( getName(), service.getDefaultNamespace() ) );
180         setDocumentation( configuration.getTextTrim() );
181         
182         Attribute xsdAt = configuration.attribute("schemaType");
183         if ( xsdAt != null )
184         {
185             setSchemaType( null );
186         }
187         else
188         {
189             setSchemaType( QName.get(getName(), service.getDefaultNamespace() ) );
190         }
191         
192         List childElements = configuration.elements();
193         for ( Iterator itr = childElements.iterator(); itr.hasNext(); )
194         {
195             Element paramEl = (Element) itr.next();
196             QName typeQ = QName.get(paramEl.getName(), service.getSoapVersion());
197 
198             Type type = reg.createType(typeQ);
199             type.configure(paramEl, service, reg);
200             
201             addChild(type);
202         }
203     }
204 
205 	public Set getDependencies()
206 	{
207 		Set deps = new HashSet();
208         
209         deps.addAll( getChildren() );
210         
211         return deps;
212 	}
213 }