1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package tests;
21  
22  import junit.framework.TestCase;
23  import org.apache.ws.commons.schema.*;
24  
25  import javax.xml.namespace.QName;
26  import javax.xml.transform.stream.StreamSource;
27  import java.io.FileInputStream;
28  import java.io.InputStream;
29  import java.util.HashSet;
30  import java.util.Iterator;
31  import java.util.Set;
32  
33  /*
34   * Copyright 2004,2007 The Apache Software Foundation.
35   * Copyright 2006 International Business Machines Corp.
36   *
37   * Licensed under the Apache License, Version 2.0 (the "License");
38   * you may not use this file except in compliance with the License.
39   * You may obtain a copy of the License at
40   *
41   *      http://www.apache.org/licenses/LICENSE-2.0
42   *
43   * Unless required by applicable law or agreed to in writing, software
44   * distributed under the License is distributed on an "AS IS" BASIS,
45   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46   * See the License for the specific language governing permissions and
47   * limitations under the License.
48   * 
49   * @author Brent Ulbricht 
50   */
51  public class RedefineTest extends TestCase {
52  
53      /**
54       * This method will test a complex type redefine.
55       *
56       * @throws Exception Any exception encountered
57       */
58      public void testComplexTypeRedefine() throws Exception {
59  
60          /*
61          redefine1.xsd
62          -----------------
63          
64          <schema xmlns="http://www.w3.org/2001/XMLSchema"
65                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
66                  xmlns:tns="http://soapinterop.org/types"
67                  targetNamespace="http://soapinterop.org/types">
68    
69            <complexType name="person">
70              <sequence>
71                <element name="firstname" type="string"/>
72                <element name="lastname" type="string"/>
73              </sequence>
74            </complexType>
75  
76            <element name="customer" type="tns:person"/>
77  
78          </schema>
79          
80                           
81          redefine2.xsd
82          -----------------
83          
84          <schema xmlns="http://www.w3.org/2001/XMLSchema"
85                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
86                  xmlns:tns="http://soapinterop.org/types"
87                  targetNamespace="http://soapinterop.org/types">
88  
89            <redefine schemaLocation="src/test/test-resources/redefine1.xsd">
90              <complexType name="person">
91                <complexContent>
92                  <extension base="tns:person">
93                    <sequence>
94                      <element name="id" type="string"/>
95                    </sequence>
96                  </extension>
97                </complexContent>
98              </complexType>
99            </redefine>
100 
101           <element name="vip" type="tns:person"/>
102 
103         </schema>
104         */
105 
106         InputStream is = new FileInputStream(Resources.asURI("redefine2.xsd"));
107         XmlSchemaCollection schemaCol = new XmlSchemaCollection();
108         XmlSchema schema = schemaCol.read(new StreamSource(is), null);
109 
110         XmlSchemaObjectTable xsot = schema.getElements();
111         assertEquals(1, xsot.getCount());
112 
113         XmlSchemaElement xse = null;
114         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
115             xse = (XmlSchemaElement)i.next();
116         }
117         assertEquals("vip", xse.getName());
118         assertEquals(new QName("http://soapinterop.org/types",
119                                "person"),
120                      xse.getSchemaTypeName());
121 
122         XmlSchemaObjectCollection xsoc = schema.getIncludes();
123         assertEquals(1, xsoc.getCount());
124         
125         XmlSchemaRedefine xsr = (XmlSchemaRedefine)xsoc.getItem(0);
126         xsot = xsr.getSchemaTypes();
127         assertEquals(1, xsot.getCount());
128 
129         for (Iterator i = xsot.getNames(); i.hasNext(); ) {
130             QName qname = (QName)i.next();
131             assertEquals(new QName("http://soapinterop.org/types",
132                                    "person"), qname);
133         }
134 
135         XmlSchemaComplexType xsct = null;
136         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
137             xsct = (XmlSchemaComplexType)i.next();
138         }
139         assertNotNull(xsct);
140 
141         XmlSchemaContentModel xscm = xsct.getContentModel();
142         assertNotNull(xscm);
143 
144         XmlSchemaComplexContentExtension xscce =
145             (XmlSchemaComplexContentExtension)xscm.getContent();
146         assertEquals(new QName("http://soapinterop.org/types",
147                                "person"),
148                      xscce.getBaseTypeName());
149 
150         XmlSchemaSequence xsp = (XmlSchemaSequence)xscce.getParticle();
151         assertNotNull(xsp);
152 
153         XmlSchemaObjectCollection c = xsp.getItems();
154         assertEquals(1, c.getCount());
155 
156         xse = null;
157         for (int i = 0; i < c.getCount(); i++) {
158             xse = (XmlSchemaElement)c.getItem(i);
159         }
160         assertEquals("id", xse.getName());
161         assertEquals(new QName("http://www.w3.org/2001/XMLSchema",
162                                "string"),
163                      xse.getSchemaTypeName());
164 
165     }
166 
167     /**
168      * This method will test a simple type redefine.
169      *
170      * @throws Exception Any exception encountered
171      */
172     public void testSimpleTypeRedefine() throws Exception {
173         /*
174         
175         redefine3.xsd
176         -----------------
177         
178         <schema xmlns="http://www.w3.org/2001/XMLSchema"
179                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
180                 xmlns:tns="http://soapinterop.org/types"
181                 targetNamespace="http://soapinterop.org/types">
182   
183           <simpleType name="drinksize">
184             <restriction base="integer"/>
185           </simpleType>
186           
187           <element name="size" type="tns:drinksize"/>
188 
189         </schema>
190         
191                                                   
192         redefine4.xsd
193         -----------------
194         
195         <schema xmlns="http://www.w3.org/2001/XMLSchema"
196                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
197                 xmlns:tns="http://soapinterop.org/types"
198                 targetNamespace="http://soapinterop.org/types">
199 
200           <redefine schemaLocation="test-resources/redefine3.xsd">
201             <simpleType name="drinksize">
202               <restriction base="tns:drinksize">
203                 <minInclusive value="1"/>
204                 <maxInclusive value="3"/>
205               </restriction>
206             </simpleType>
207           </redefine>
208           
209           <element name="childsizedrink" type="tns:drinksize"/>
210 
211         </schema>
212         */
213 
214         InputStream is = new FileInputStream(Resources.asURI("redefine4.xsd"));
215         XmlSchemaCollection schemaCol = new XmlSchemaCollection();
216         XmlSchema schema = schemaCol.read(new StreamSource(is), null);
217 
218         XmlSchemaObjectTable xsot = schema.getElements();
219         assertEquals(1, xsot.getCount());
220 
221         XmlSchemaElement xse = null;
222         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
223             xse = (XmlSchemaElement)i.next();
224         }
225         assertEquals("childsizedrink", xse.getName());
226         assertEquals(new QName("http://soapinterop.org/types",
227                                "drinksize"),
228                      xse.getSchemaTypeName());
229 
230         XmlSchemaObjectCollection xsoc = schema.getIncludes();
231         assertEquals(1, xsoc.getCount());
232         
233         XmlSchemaRedefine xsr = (XmlSchemaRedefine)xsoc.getItem(0);
234         xsot = xsr.getSchemaTypes();
235         assertEquals(1, xsot.getCount());
236 
237         for (Iterator i = xsot.getNames(); i.hasNext(); ) {
238             QName qname = (QName)i.next();
239             assertEquals(new QName("http://soapinterop.org/types",
240                                    "drinksize"), qname);
241         }
242 
243         XmlSchemaSimpleType xsst = null;
244         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
245             xsst = (XmlSchemaSimpleType)i.next();
246         }
247         assertNotNull(xsst);
248 
249         XmlSchemaSimpleTypeRestriction xsstr =
250             (XmlSchemaSimpleTypeRestriction)xsst.getContent();
251         assertEquals(new QName("http://soapinterop.org/types",
252                                "drinksize"),
253                      xsstr.getBaseTypeName());
254 
255         xsoc = xsstr.getFacets();
256 
257         Set s = new HashSet();
258         s.add(XmlSchemaMinInclusiveFacet.class.getName());
259         s.add(XmlSchemaMaxInclusiveFacet.class.getName());
260         for (Iterator i  = xsoc.getIterator(); i.hasNext(); ) {
261             Object o = i.next();
262             assertTrue(s.remove(o.getClass().getName()));
263             if (o instanceof XmlSchemaMinInclusiveFacet) {
264                 assertEquals("1", ((XmlSchemaMinInclusiveFacet)o).getValue());
265             } else if (o instanceof XmlSchemaMaxInclusiveFacet) {
266                 assertEquals("3", ((XmlSchemaMaxInclusiveFacet)o).getValue());
267             } else {
268                 fail("Unexpected object encountered: "
269                      + o.getClass().getName());
270             }
271         }
272 
273         assertTrue("The set should have been empty, but instead contained: "
274                    + s + ".",
275                    s.isEmpty());
276 
277     }
278 
279     /**
280      * This method will test a group redefine.
281      *
282      * @throws Exception Any exception encountered
283      */
284     public void testGroupRedefine() throws Exception {
285 
286         /*
287         redefine5.xsd
288         -----------------
289         
290         <schema xmlns="http://www.w3.org/2001/XMLSchema"
291                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
292                 xmlns:tns="http://soapinterop.org/types"
293                 targetNamespace="http://soapinterop.org/types">
294   
295           <group name="PrologGroup">
296             <sequence>
297               <element name="date" type="string"/>
298               <element name="author" type="string"/>
299               <element name="defect" type="integer"/>
300             </sequence>
301           </group>
302           
303         </schema>
304 
305 
306         redefine6.xsd
307         -----------------
308 
309         <schema xmlns="http://www.w3.org/2001/XMLSchema"
310                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
311                 xmlns:tns="http://soapinterop.org/types"
312                 targetNamespace="http://soapinterop.org/types">
313 
314           <redefine schemaLocation="redefine5.xsd">
315             <group name="PrologGroup">
316               <sequence>
317                 <group ref="tns:PrologGroup"/>
318                 <element name="description" type="string"/>
319               </sequence>
320             </group>
321           </redefine>
322 
323         </schema>
324         */
325 
326         InputStream is = new FileInputStream(Resources.asURI("redefine6.xsd"));
327         XmlSchemaCollection schemaCol = new XmlSchemaCollection();
328         XmlSchema schema = schemaCol.read(new StreamSource(is), null);
329 
330         XmlSchemaObjectCollection xsoc = schema.getIncludes();
331         assertEquals(1, xsoc.getCount());
332         
333         XmlSchemaRedefine xsr = (XmlSchemaRedefine)xsoc.getItem(0);
334         XmlSchemaObjectTable xsot = xsr.getGroup();
335         assertEquals(1, xsot.getCount());
336 
337         for (Iterator i = xsot.getNames(); i.hasNext(); ) {
338             assertEquals("PrologGroup", ((QName)i.next()).getLocalPart());
339         }
340 
341         XmlSchemaGroup xsg = null;
342         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
343             xsg = (XmlSchemaGroup)i.next();
344         }
345 
346         XmlSchemaSequence xss = (XmlSchemaSequence)xsg.getParticle();
347 
348         xsoc = xss.getItems();
349         assertEquals(2, xsoc.getCount());
350         
351         Set s = new HashSet();
352         s.add(XmlSchemaGroupRef.class.getName());
353         s.add(XmlSchemaElement.class.getName());
354         for (Iterator i  = xsoc.getIterator(); i.hasNext(); ) {
355             Object o = i.next();
356             assertTrue(s.remove(o.getClass().getName()));
357             if (o instanceof XmlSchemaGroupRef) {
358                 assertEquals(new QName("http://soapinterop.org/types",
359                                        "PrologGroup"),
360                              ((XmlSchemaGroupRef)o).getRefName());
361             } else if (o instanceof XmlSchemaElement) {
362                 assertEquals("description", ((XmlSchemaElement)o).getName());
363             } else {
364                 fail("Unexpected object encountered: "
365                      + o.getClass().getName());
366             }
367         }
368 
369         assertTrue("The set should have been empty, but instead contained: "
370                    + s + ".",
371                    s.isEmpty());
372 
373     }
374 
375     /**
376      * This method will test a attribute group redefine.
377      *
378      * @throws Exception Any exception encountered
379      */
380     public void testAttributeGroupRedefine() throws Exception {
381 
382         /*
383         redefine7.xsd
384         -----------------
385         
386         <schema xmlns="http://www.w3.org/2001/XMLSchema"
387                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
388                 xmlns:tns="http://soapinterop.org/types"
389                 targetNamespace="http://soapinterop.org/types">
390   
391           <attributeGroup name="AttribGroup">
392             <attribute name="type" type="string"/>
393             <attribute name="units" type="string"/>
394             <attribute name="serialId" type="string"/>
395           </attributeGroup>
396           
397         </schema>
398 
399 
400         redefine8.xsd
401         -----------------
402 
403         <schema xmlns="http://www.w3.org/2001/XMLSchema"
404                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
405                 xmlns:tns="http://soapinterop.org/types"
406                 targetNamespace="http://soapinterop.org/types">
407 
408           <redefine schemaLocation="redefine7.xsd">
409             <attributeGroup name="AttribGroup">
410               <attribute name="type" type="string"/>
411               <attribute name="units" type="string"/>
412             </attributeGroup>
413           </redefine>
414 
415         </schema>
416         */
417 
418         InputStream is = new FileInputStream(Resources.asURI("redefine8.xsd"));
419         XmlSchemaCollection schemaCol = new XmlSchemaCollection();
420         XmlSchema schema = schemaCol.read(new StreamSource(is), null);
421 
422         XmlSchemaObjectCollection xsoc = schema.getIncludes();
423         assertEquals(1, xsoc.getCount());
424         
425         XmlSchemaRedefine xsr = (XmlSchemaRedefine)xsoc.getItem(0);
426         XmlSchemaObjectTable xsot = xsr.getAttributeGroup();
427         assertEquals(1, xsot.getCount());
428 
429         for (Iterator i = xsot.getNames(); i.hasNext(); ) {
430             assertEquals("AttribGroup", ((QName)i.next()).getLocalPart());
431         }
432 
433         XmlSchemaAttributeGroup xsag = null;
434         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
435             xsag = (XmlSchemaAttributeGroup)i.next();
436         }
437 
438         assertNotNull(xsag);
439         assertEquals("AttribGroup", (xsag.getName()).getLocalPart());
440         xsoc = xsag.getAttributes();
441 
442         Set s = new HashSet();
443         s.add("type");
444         s.add("units");
445         for (Iterator i  = xsoc.getIterator(); i.hasNext(); ) {
446             XmlSchemaAttribute xsa = (XmlSchemaAttribute)i.next();
447             assertTrue(s.remove(xsa.getName()));
448         }
449 
450         assertTrue("The set should have been empty, but instead contained: "
451                    + s + ".",
452                    s.isEmpty());
453         
454     }
455 
456 
457     /**
458      * This method will test a complex type redefine. Similar
459      * to the first test but now there are multiple layers of includes
460      *
461      * @throws Exception Any exception encountered
462      */
463     public void testComplexTypeRedefineWithRelativeImports() throws Exception {
464 
465     	/*
466     	 * redefine-import2.xsd
467     	 * 
468 		    	  <schema xmlns="http://www.w3.org/2001/XMLSchema"
469 		        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
470 		        xmlns:tns="http://soapinterop.org/types"
471 		        targetNamespace="http://soapinterop.org/types">
472 		        
473 		<complexType name="person">
474 		    <sequence>
475 		      <element name="firstname" type="string"/>
476 		      <element name="lastname" type="string"/>
477 		    </sequence>
478 		  </complexType>
479 		
480 		  <element name="customer" type="tns:person"/>
481 		 
482 		 </schema>
483     	 * 
484     	 * 
485     	 */
486     	
487     	
488     	/*
489     	 * redefine-import1.xsd
490     	 * 
491     	 * 
492 		 <schema xmlns="http://www.w3.org/2001/XMLSchema"
493 		        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
494 		        xmlns:tns="http://soapinterop.org/types"
495 		        targetNamespace="http://soapinterop.org/types">
496 		 <!--  relative import to this location -->       
497 		 <xsd:include schemaLocation="redefine-import2.xsd"></xsd:include>
498 		 
499 		 </schema>
500     	 * 
501     	 */
502         /*
503         redefine9.xsd
504         -----------------
505 	        
506 	        <schema xmlns="http://www.w3.org/2001/XMLSchema"
507 	        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
508 	        xmlns:tns="http://soapinterop.org/types"
509 	        targetNamespace="http://soapinterop.org/types">
510 	        
511 	  <!-- Relative import -->
512 	  <xsd:include schemaLocation="redefine-include/redefine-import1.xsd"></xsd:include>
513 	
514 	</schema>
515 	        
516                          
517         redefine10.xsd
518         -----------------
519         
520 	<schema xmlns="http://www.w3.org/2001/XMLSchema"
521 	        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
522 	        xmlns:tns="http://soapinterop.org/types"
523 	        targetNamespace="http://soapinterop.org/types">
524 	
525 	  <redefine schemaLocation="src/test/test-resources/redefine9.xsd">
526 	    <complexType name="person">
527 	      <complexContent>
528 	        <extension base="tns:person">
529 	          <sequence>
530 	            <element name="id" type="string"/>
531 	          </sequence>
532 	        </extension>
533 	      </complexContent>
534 	    </complexType>
535 	  </redefine>
536 	
537 	  <element name="vip" type="tns:person"/>
538 	
539 	</schema>
540         */
541 
542         InputStream is = new FileInputStream(Resources.asURI("redefine10.xsd"));
543         XmlSchemaCollection schemaCol = new XmlSchemaCollection();
544         XmlSchema schema = schemaCol.read(new StreamSource(is), null);
545 
546         XmlSchemaObjectTable xsot = schema.getElements();
547         assertEquals(1, xsot.getCount());
548 
549         XmlSchemaElement xse = null;
550         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
551             xse = (XmlSchemaElement)i.next();
552         }
553         assertEquals("vip", xse.getName());
554         assertEquals(new QName("http://soapinterop.org/types",
555                                "person"),
556                      xse.getSchemaTypeName());
557 
558         XmlSchemaObjectCollection xsoc = schema.getIncludes();
559         assertEquals(1, xsoc.getCount());
560         
561         XmlSchemaRedefine xsr = (XmlSchemaRedefine)xsoc.getItem(0);
562         xsot = xsr.getSchemaTypes();
563         assertEquals(1, xsot.getCount());
564 
565         for (Iterator i = xsot.getNames(); i.hasNext(); ) {
566             QName qname = (QName)i.next();
567             assertEquals(new QName("http://soapinterop.org/types",
568                                    "person"), qname);
569         }
570 
571         XmlSchemaComplexType xsct = null;
572         for (Iterator i = xsot.getValues(); i.hasNext(); ) {
573             xsct = (XmlSchemaComplexType)i.next();
574         }
575         assertNotNull(xsct);
576 
577         XmlSchemaContentModel xscm = xsct.getContentModel();
578         assertNotNull(xscm);
579 
580         XmlSchemaComplexContentExtension xscce =
581             (XmlSchemaComplexContentExtension)xscm.getContent();
582         assertEquals(new QName("http://soapinterop.org/types",
583                                "person"),
584                      xscce.getBaseTypeName());
585 
586         XmlSchemaSequence xsp = (XmlSchemaSequence)xscce.getParticle();
587         assertNotNull(xsp);
588 
589         XmlSchemaObjectCollection c = xsp.getItems();
590         assertEquals(1, c.getCount());
591 
592         xse = null;
593         for (int i = 0; i < c.getCount(); i++) {
594             xse = (XmlSchemaElement)c.getItem(i);
595         }
596         assertEquals("id", xse.getName());
597         assertEquals(new QName("http://www.w3.org/2001/XMLSchema",
598                                "string"),
599                      xse.getSchemaTypeName());
600 
601     }
602 }