1 package org.codehaus.xfire.xmlbeans;
2
3 import java.util.HashSet;
4 import java.util.Iterator;
5 import java.util.Map;
6 import java.util.Set;
7
8 import javax.xml.namespace.QName;
9 import javax.xml.stream.XMLStreamException;
10 import javax.xml.stream.XMLStreamReader;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.apache.xmlbeans.SchemaProperty;
15 import org.apache.xmlbeans.SchemaType;
16 import org.apache.xmlbeans.XmlBeans;
17 import org.apache.xmlbeans.XmlCursor;
18 import org.apache.xmlbeans.XmlException;
19 import org.apache.xmlbeans.XmlObject;
20 import org.codehaus.xfire.MessageContext;
21 import org.codehaus.xfire.XFireRuntimeException;
22 import org.codehaus.xfire.aegis.MessageReader;
23 import org.codehaus.xfire.aegis.MessageWriter;
24 import org.codehaus.xfire.aegis.stax.ElementReader;
25 import org.codehaus.xfire.aegis.stax.ElementWriter;
26 import org.codehaus.xfire.aegis.type.Type;
27 import org.codehaus.xfire.fault.XFireFault;
28 import org.codehaus.xfire.soap.handler.ReadHeadersHandler;
29 import org.codehaus.xfire.util.STAXUtils;
30 import org.codehaus.yom.Element;
31
32 /***
33 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
34 * @since Nov 13, 2004
35 */
36 public class XmlBeansType
37 extends Type
38 {
39 private SchemaType schemaType;
40
41 private final static Log logger = LogFactory.getLog(XmlBeansType.class);
42
43 public XmlBeansType()
44 {
45 }
46
47 public XmlBeansType(SchemaType schemaType)
48 {
49 this.schemaType = schemaType;
50 setTypeClass(schemaType.getJavaClass());
51 }
52
53 public XmlBeansType(Class clazz)
54 {
55 this.schemaType = XmlBeans.typeForClass(clazz);
56 setTypeClass(clazz);
57 }
58
59 public void writeSchema(Element root)
60 {
61 }
62
63 public boolean isComplex()
64 {
65 return !schemaType.isPrimitiveType();
66 }
67
68 public boolean isAbstract()
69 {
70 return schemaType.isAbstract();
71 }
72
73 public Set getDependencies()
74 {
75 SchemaProperty[] properties = schemaType.getProperties();
76 HashSet deps = new HashSet();
77 for (int i = 0; i < properties.length; i++)
78 {
79 SchemaType etype = properties[i].getType();
80 SchemaProperty[] iprops = etype.getElementProperties();
81 for (int j = 0; j < iprops.length; j++)
82 {
83 SchemaType itype = iprops[j].getType();
84
85 if (!itype.isPrimitiveType() && itype.getSourceName() != null)
86 {
87 deps.add(new XmlBeansType(itype));
88 }
89 }
90 }
91 return deps;
92 }
93
94 public QName getSchemaType()
95 {
96 if (schemaType.isDocumentType())
97 return schemaType.getDocumentElementName();
98 else if (schemaType.getName() != null)
99 return schemaType.getName();
100 else
101 {
102
103 SchemaType outer = schemaType.getOuterType();
104 while (outer != null)
105 {
106 if (outer.isDocumentType())
107 return outer.getDocumentElementName();
108 else if (outer.getName() != null)
109 return outer.getName();
110 else
111 outer = outer.getOuterType();
112 }
113
114
115 throw new XFireRuntimeException("No type name is defined for <" + schemaType + "> " +
116 "and no outer type containing the inline type -- this " +
117 "should not be possible to be a legally defined schema");
118 }
119 }
120
121 public Object readObject(MessageReader mreader, MessageContext context)
122 throws XFireFault
123 {
124 try
125 {
126 XMLStreamReader reader = ((ElementReader) mreader).getXMLStreamReader();
127 XmlObject parsed = XmlObject.Factory.parse(reader);
128
129
130
131
132
133
134 XmlCursor cursor = parsed.newCursor();
135 try
136 {
137 cursor.toFirstContentToken();
138 Map namespaces = (Map) context.getProperty(ReadHeadersHandler.DECLARED_NAMESPACES);
139 for (Iterator itr = namespaces.entrySet().iterator(); itr.hasNext();)
140 {
141 Map.Entry entry = (Map.Entry) itr.next();
142 cursor.insertNamespace((String) entry.getKey(), (String) entry.getValue());
143 }
144 }
145 finally
146 {
147 cursor.dispose();
148 }
149
150 return parsed;
151 }
152 catch( XmlException e )
153 {
154 throw new XFireFault("Could not read request.", e, XFireFault.SENDER);
155 }
156 }
157
158 public void writeObject(Object value, MessageWriter writer, MessageContext context)
159 throws XFireFault
160 {
161 try
162 {
163 XmlObject obj = (XmlObject) value;
164
165 XmlCursor cursor = obj.newCursor();
166 if (cursor.toFirstChild() && cursor.toFirstChild())
167 {
168 do
169 {
170 STAXUtils.copy(cursor.newXMLStreamReader(),
171 ((ElementWriter) writer).getXMLStreamWriter());
172 }
173 while(cursor.toNextSibling());
174 }
175 }
176 catch (XMLStreamException e)
177 {
178 throw new XFireFault("Could not write response.", e, XFireFault.SENDER);
179 }
180 }
181 }