001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.jaxb;
019:
020: import java.io.ByteArrayInputStream;
021: import java.io.ByteArrayOutputStream;
022: import java.io.InputStream;
023: import java.lang.reflect.Method;
024: import java.lang.reflect.Type;
025:
026: import javax.xml.XMLConstants;
027: import javax.xml.bind.JAXBContext;
028: import javax.xml.bind.JAXBElement;
029: import javax.xml.bind.Unmarshaller;
030: import javax.xml.namespace.QName;
031: import javax.xml.stream.XMLEventReader;
032: import javax.xml.stream.XMLEventWriter;
033: import javax.xml.stream.XMLInputFactory;
034: import javax.xml.stream.XMLOutputFactory;
035: import javax.xml.stream.XMLStreamReader;
036: import javax.xml.transform.stream.StreamSource;
037: import javax.xml.validation.Schema;
038: import javax.xml.validation.SchemaFactory;
039: import javax.xml.ws.RequestWrapper;
040:
041: import org.w3c.dom.Document;
042: import org.w3c.dom.Element;
043: import org.w3c.dom.Node;
044:
045: import org.apache.cxf.helpers.DOMUtils;
046: import org.apache.cxf.interceptor.Fault;
047: import org.apache.cxf.jaxb_misc.Base64WithDefaultValueType;
048: import org.apache.cxf.jaxb_misc.ObjectFactory;
049: import org.apache.cxf.service.model.MessagePartInfo;
050: import org.apache.cxf.staxutils.StaxStreamFilter;
051: import org.apache.cxf.testutil.common.TestUtil;
052: import org.apache.hello_world_soap_http.Greeter;
053: import org.apache.hello_world_soap_http.types.GreetMe;
054: import org.apache.hello_world_soap_http.types.GreetMeResponse;
055: import org.apache.hello_world_soap_http.types.StringStruct;
056: import org.apache.type_test.doc.TypeTestPortType;
057: import org.junit.Assert;
058: import org.junit.Before;
059: import org.junit.Test;
060:
061: /**
062: * JAXBEncoderDecoderTest
063: * @author apaibir
064: */
065: public class JAXBEncoderDecoderTest extends Assert {
066: public static final QName SOAP_ENV = new QName(
067: "http://schemas.xmlsoap.org/soap/envelope/", "Envelope");
068: public static final QName SOAP_BODY = new QName(
069: "http://schemas.xmlsoap.org/soap/envelope/", "Body");
070:
071: RequestWrapper wrapperAnnotation;
072: JAXBContext context;
073: Schema schema;
074:
075: public JAXBEncoderDecoderTest() {
076: }
077:
078: public JAXBEncoderDecoderTest(String arg0) {
079: }
080:
081: @Before
082: public void setUp() throws Exception {
083:
084: context = JAXBContext.newInstance(new Class[] { GreetMe.class,
085: GreetMeResponse.class, StringStruct.class });
086: Method method = TestUtil.getMethod(Greeter.class, "greetMe");
087: wrapperAnnotation = method.getAnnotation(RequestWrapper.class);
088:
089: InputStream is = getClass().getResourceAsStream(
090: "resources/StringStruct.xsd");
091: StreamSource schemaSource = new StreamSource(is);
092: assertNotNull(schemaSource);
093: SchemaFactory factory = SchemaFactory
094: .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
095: schema = factory.newSchema(schemaSource);
096: assertNotNull(schema);
097: }
098:
099: @Test
100: public void testMarshallIntoDOM() throws Exception {
101: String str = new String("Hello");
102: QName inCorrectElName = new QName("http://test_jaxb_marshall",
103: "requestType");
104: MessagePartInfo part = new MessagePartInfo(inCorrectElName,
105: null);
106: part.setElement(true);
107: part.setElementQName(inCorrectElName);
108:
109: Document doc = DOMUtils.createDocument();
110: Element elNode = doc.createElementNS(inCorrectElName
111: .getNamespaceURI(), inCorrectElName.getLocalPart());
112: assertNotNull(elNode);
113:
114: Node node;
115: try {
116: JAXBEncoderDecoder.marshall(context, null, null, part,
117: elNode);
118: fail("Should have thrown a Fault");
119: } catch (Fault ex) {
120: //expected - not a valid object
121: }
122:
123: GreetMe obj = new GreetMe();
124: obj.setRequestType("Hello");
125: QName elName = new QName(wrapperAnnotation.targetNamespace(),
126: wrapperAnnotation.localName());
127: part.setElementQName(elName);
128: JAXBEncoderDecoder.marshall(context, null, obj, part, elNode);
129: node = elNode.getLastChild();
130: //The XML Tree Looks like
131: //<GreetMe><requestType>Hello</requestType></GreetMe>
132: assertEquals(Node.ELEMENT_NODE, node.getNodeType());
133: Node childNode = node.getFirstChild();
134: assertEquals(Node.ELEMENT_NODE, childNode.getNodeType());
135: childNode = childNode.getFirstChild();
136: assertEquals(Node.TEXT_NODE, childNode.getNodeType());
137: assertEquals(str, childNode.getNodeValue());
138:
139: // Now test schema validation during marshaling
140: StringStruct stringStruct = new StringStruct();
141: // Don't initialize one of the structure members.
142: //stringStruct.setArg0("hello");
143: stringStruct.setArg1("world");
144: // Marshal without the schema should work.
145: JAXBEncoderDecoder.marshall(context, null, stringStruct, part,
146: elNode);
147: try {
148: // Marshal with the schema should get an exception.
149: JAXBEncoderDecoder.marshall(context, schema, stringStruct,
150: part, elNode);
151: fail("Marshal with schema should have thrown a Fault");
152: } catch (Fault ex) {
153: //expected - not a valid object
154: }
155: }
156:
157: @Test
158: public void testMarshallIntoStax() throws Exception {
159: GreetMe obj = new GreetMe();
160: obj.setRequestType("Hello");
161: QName elName = new QName(wrapperAnnotation.targetNamespace(),
162: wrapperAnnotation.localName());
163: MessagePartInfo part = new MessagePartInfo(elName, null);
164: part.setElement(true);
165: part.setElementQName(elName);
166:
167: ByteArrayOutputStream baos = new ByteArrayOutputStream();
168: XMLOutputFactory opFactory = XMLOutputFactory.newInstance();
169: opFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
170: Boolean.TRUE);
171: XMLEventWriter writer = opFactory.createXMLEventWriter(baos);
172:
173: //STARTDOCUMENT/ENDDOCUMENT is not required
174: //writer.add(eFactory.createStartDocument("utf-8", "1.0"));
175: JAXBEncoderDecoder.marshall(context, null, obj, part, writer);
176: //writer.add(eFactory.createEndDocument());
177: writer.flush();
178: writer.close();
179:
180: //System.out.println(baos.toString());
181:
182: ByteArrayInputStream bais = new ByteArrayInputStream(baos
183: .toByteArray());
184: XMLInputFactory ipFactory = XMLInputFactory.newInstance();
185: XMLEventReader reader = ipFactory.createXMLEventReader(bais);
186:
187: Unmarshaller um = context.createUnmarshaller();
188: Object val = um.unmarshal(reader, GreetMe.class);
189: assertTrue(val instanceof JAXBElement);
190: val = ((JAXBElement) val).getValue();
191: assertTrue(val instanceof GreetMe);
192: assertEquals(obj.getRequestType(), ((GreetMe) val)
193: .getRequestType());
194: }
195:
196: @Test
197: public void testUnmarshallFromStax() throws Exception {
198: QName elName = new QName(wrapperAnnotation.targetNamespace(),
199: wrapperAnnotation.localName());
200: MessagePartInfo part = new MessagePartInfo(elName, null);
201:
202: InputStream is = getClass().getResourceAsStream(
203: "resources/GreetMeDocLiteralReq.xml");
204: XMLInputFactory factory = XMLInputFactory.newInstance();
205: XMLStreamReader reader = factory.createXMLStreamReader(is);
206:
207: QName[] tags = { SOAP_ENV, SOAP_BODY };
208: StaxStreamFilter filter = new StaxStreamFilter(tags);
209: reader = factory.createFilteredReader(reader, filter);
210:
211: //Remove START_DOCUMENT & START_ELEMENT pertaining to Envelope and Body Tags.
212:
213: part.setTypeClass(GreetMe.class);
214: Object val = JAXBEncoderDecoder.unmarshall(context, null,
215: reader, part, null, true);
216: assertNotNull(val);
217: assertTrue(val instanceof GreetMe);
218: assertEquals("TestSOAPInputPMessage", ((GreetMe) val)
219: .getRequestType());
220:
221: is.close();
222: }
223:
224: @Test
225: public void testMarshalRPCLit() throws Exception {
226: QName elName = new QName("http://test_jaxb_marshall", "in");
227: MessagePartInfo part = new MessagePartInfo(elName, null);
228: part.setElement(true);
229: part.setElementQName(elName);
230:
231: Document doc = DOMUtils.createDocument();
232: Element elNode = doc.createElementNS(elName.getNamespaceURI(),
233: elName.getLocalPart());
234: JAXBEncoderDecoder.marshall(context, null, new String(
235: "TestSOAPMessage"), part, elNode);
236:
237: assertNotNull(elNode.getChildNodes());
238: assertEquals("TestSOAPMessage", elNode.getFirstChild()
239: .getFirstChild().getNodeValue());
240: }
241:
242: @Test
243: public void testUnMarshall() throws Exception {
244: //Hello World Wsdl generated namespace
245: QName elName = new QName(wrapperAnnotation.targetNamespace(),
246: wrapperAnnotation.localName());
247:
248: MessagePartInfo part = new MessagePartInfo(elName, null);
249: part.setElement(true);
250: part.setElementQName(elName);
251: part.setTypeClass(Class.forName(wrapperAnnotation.className()));
252:
253: Document doc = DOMUtils.createDocument();
254: Element elNode = doc.createElementNS(elName.getNamespaceURI(),
255: elName.getLocalPart());
256: Element rtEl = doc.createElementNS(elName.getNamespaceURI(),
257: "requestType");
258: elNode.appendChild(rtEl);
259: rtEl.appendChild(doc.createTextNode("Hello Test"));
260:
261: Object obj = JAXBEncoderDecoder.unmarshall(context, null,
262: elNode, part, null, true);
263: assertNotNull(obj);
264:
265: //Add a Node and then test
266: assertEquals(GreetMe.class, obj.getClass());
267: assertEquals("Hello Test", ((GreetMe) obj).getRequestType());
268:
269: part.setTypeClass(String.class);
270: Node n = null;
271: try {
272: JAXBEncoderDecoder.unmarshall(context, null, n, part, null,
273: true);
274: fail("Should have received a Fault");
275: } catch (Fault pe) {
276: //Expected Exception
277: } catch (Exception ex) {
278: fail("Should have received a Fault, not: " + ex);
279: }
280:
281: // Now test schema validation during unmarshaling
282: elName = new QName(wrapperAnnotation.targetNamespace(),
283: "stringStruct");
284: // Create an XML Tree of
285: // <StringStruct><arg1>World</arg1></StringStruct>
286: // elNode = soapElFactory.createElement(elName);
287: // elNode.addNamespaceDeclaration("", elName.getNamespaceURI());
288:
289: part = new MessagePartInfo(elName, null);
290: part.setElement(true);
291: part.setElementQName(elName);
292: part
293: .setTypeClass(Class
294: .forName("org.apache.hello_world_soap_http.types.StringStruct"));
295:
296: doc = DOMUtils.createDocument();
297: elNode = doc.createElementNS(elName.getNamespaceURI(), elName
298: .getLocalPart());
299: rtEl = doc.createElementNS(elName.getNamespaceURI(), "arg1");
300: elNode.appendChild(rtEl);
301: rtEl.appendChild(doc.createTextNode("World"));
302:
303: // Should unmarshal without problems when no schema used.
304: obj = JAXBEncoderDecoder.unmarshall(context, null, elNode,
305: part, null, true);
306: assertNotNull(obj);
307: assertEquals(StringStruct.class, obj.getClass());
308: assertEquals("World", ((StringStruct) obj).getArg1());
309:
310: try {
311: // unmarshal with schema should raise exception.
312: obj = JAXBEncoderDecoder.unmarshall(context, schema,
313: elNode, part, null, true);
314: fail("Should have thrown a Fault");
315: } catch (Fault ex) {
316: // expected - schema validation should fail.
317: }
318: }
319:
320: @Test
321: public void testUnmarshallWithoutClzInfo() throws Exception {
322: QName elName = new QName(wrapperAnnotation.targetNamespace(),
323: wrapperAnnotation.localName());
324:
325: Document doc = DOMUtils.createDocument();
326: Element elNode = doc.createElementNS(elName.getNamespaceURI(),
327: elName.getLocalPart());
328: Element rtEl = doc.createElementNS(elName.getNamespaceURI(),
329: "requestType");
330: elNode.appendChild(rtEl);
331: rtEl.appendChild(doc.createTextNode("Hello Test"));
332:
333: Object obj = JAXBEncoderDecoder.unmarshall(context, null,
334: elNode);
335: assertNotNull(obj);
336: assertEquals(GreetMe.class, obj.getClass());
337: assertEquals("Hello Test", ((GreetMe) obj).getRequestType());
338: }
339:
340: @Test
341: public void testMarshallWithoutQNameInfo() throws Exception {
342: GreetMe obj = new GreetMe();
343: obj.setRequestType("Hello");
344:
345: ByteArrayOutputStream baos = new ByteArrayOutputStream();
346: XMLOutputFactory opFactory = XMLOutputFactory.newInstance();
347: opFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
348: Boolean.TRUE);
349: XMLEventWriter writer = opFactory.createXMLEventWriter(baos);
350:
351: //STARTDOCUMENT/ENDDOCUMENT is not required
352: //writer.add(eFactory.createStartDocument("utf-8", "1.0"));
353: JAXBEncoderDecoder.marshall(context, null, obj, writer);
354: //writer.add(eFactory.createEndDocument());
355: writer.flush();
356: writer.close();
357:
358: //System.out.println(baos.toString());
359:
360: ByteArrayInputStream bais = new ByteArrayInputStream(baos
361: .toByteArray());
362: XMLInputFactory ipFactory = XMLInputFactory.newInstance();
363: XMLEventReader reader = ipFactory.createXMLEventReader(bais);
364:
365: Unmarshaller um = context.createUnmarshaller();
366: Object val = um.unmarshal(reader, GreetMe.class);
367: assertTrue(val instanceof JAXBElement);
368: val = ((JAXBElement) val).getValue();
369: assertTrue(val instanceof GreetMe);
370: assertEquals(obj.getRequestType(), ((GreetMe) val)
371: .getRequestType());
372: }
373:
374: @Test
375: public void testGetClassFromType() throws Exception {
376: Method testByte = TestUtil.getMethod(TypeTestPortType.class,
377: "testByte");
378: Type[] genericParameterTypes = testByte
379: .getGenericParameterTypes();
380: Class<?>[] paramTypes = testByte.getParameterTypes();
381:
382: int idx = 0;
383: for (Type t : genericParameterTypes) {
384: Class<?> cls = JAXBEncoderDecoder.getClassFromType(t);
385: assertTrue(cls.equals(paramTypes[idx]));
386: idx++;
387: }
388:
389: Method testBase64Binary = TestUtil.getMethod(
390: TypeTestPortType.class, "testBase64Binary");
391: genericParameterTypes = testBase64Binary
392: .getGenericParameterTypes();
393: paramTypes = testBase64Binary.getParameterTypes();
394:
395: idx = 0;
396: for (Type t : genericParameterTypes) {
397: Class<?> cls = JAXBEncoderDecoder.getClassFromType(t);
398: assertTrue(cls.equals(paramTypes[idx]));
399: idx++;
400: }
401: }
402:
403: @Test
404: public void testDefaultValueConverter() throws Exception {
405: Base64WithDefaultValueType testData = (new ObjectFactory())
406: .createBase64WithDefaultValueType();
407: byte[] checkValue = testData.getAttributeWithDefaultValue();
408: assertNotNull(checkValue);
409: }
410: }
|