001: /**
002: * Redistribution and use of this software and associated documentation
003: * ("Software"), with or without modification, are permitted provided
004: * that the following conditions are met:
005: *
006: * 1. Redistributions of source code must retain copyright
007: * statements and notices. Redistributions must also contain a
008: * copy of this document.
009: *
010: * 2. Redistributions in binary form must reproduce the
011: * above copyright notice, this list of conditions and the
012: * following disclaimer in the documentation and/or other
013: * materials provided with the distribution.
014: *
015: * 3. The name "Exolab" must not be used to endorse or promote
016: * products derived from this Software without prior written
017: * permission of Intalio, Inc. For written permission,
018: * please contact info@exolab.org.
019: *
020: * 4. Products derived from this Software may not be called "Exolab"
021: * nor may "Exolab" appear in their names without prior written
022: * permission of Intalio, Inc. Exolab is a registered
023: * trademark of Intalio, Inc.
024: *
025: * 5. Due credit should be given to the Exolab Project
026: * (http://www.exolab.org/).
027: *
028: * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
029: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
030: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
031: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
032: * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
033: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
034: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
035: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
036: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
037: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
038: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
039: * OF THE POSSIBILITY OF SUCH DAMAGE.
040: *
041: * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved.
042: *
043: * $Id: ComplexType.java 6784 2007-01-29 03:29:17Z ekuns $
044: */package org.exolab.castor.xml.schema;
045:
046: import org.exolab.castor.xml.*;
047:
048: import java.util.Enumeration;
049:
050: /**
051: * The XML Schema ComplexType class
052: * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
053: * @version $Revision: 6784 $ $Date: 2006-02-01 15:47:48 -0700 (Wed, 01 Feb 2006) $
054: **/
055: public class ComplexType extends XMLType implements ContentModelGroup,
056: Referable {
057: /** SerialVersionUID */
058: private static final long serialVersionUID = 5348120259072084658L;
059:
060: /**
061: * The abstract flag for this ComplexType
062: **/
063: private boolean _abstract = false;
064:
065: /**
066: * A wildcard that represents an {@literal <anyAttribute>} element if any.
067: * Only one {@literal <anyAttribute>} can appear inside the global scope of
068: * a complexType
069: **/
070: private Wildcard _anyAttribute = null;
071:
072: /**
073: * The attribute declarations for this ComplexType.
074: **/
075: private AttributeGroupDecl _attributes = null;
076:
077: /**
078: * The name of the base type used in <restriction> or <extension>
079: **/
080: private String _baseType = null;
081:
082: /**
083: * The value of the 'block' property for this ComplexType. This
084: * value may be null.
085: **/
086: private BlockList _block = null;
087:
088: /**
089: * a flag set to true if this complexType is a complexContent
090: */
091: private boolean _complexContent = true;
092:
093: /**
094: * The content type ("mixed", "simpleType","elemOnly") for this ComplexType.
095: **/
096: private ContentType _content = ContentType.elemOnly;
097:
098: /**
099: * The ContentModel for this ComplexType
100: **/
101: private ContentModelGroup _contentModel = null;
102:
103: /**
104: * The final property for this ComplexType. This value may be null.
105: **/
106: private FinalList _final = null;
107:
108: /**
109: * The parent structure for this ComplexType
110: * (either an ElementDecl or a Schema)
111: **/
112: private Structure _parent = null;
113:
114: /**
115: * a flag set to true if this complexType is a restriction
116: */
117: private boolean _restricted = false;
118:
119: /**
120: * An attribute that indicates if this ComplexType is
121: * a redefinition
122: */
123: private boolean _redefinition = false;
124:
125: //------------------/
126: //- Constructor(s) -/
127: //------------------/
128:
129: /**
130: * Creates a new Complextype, with no name
131: * @param schema the owning Schema document
132: **/
133: public ComplexType(Schema schema) {
134: this (schema, null);
135: } //-- Complextype
136:
137: /**
138: * Creates a new Complextype with the given name
139: * @param schema the owning Schema
140: * @param name of the Complextype
141: **/
142: public ComplexType(Schema schema, String name) {
143: super ();
144: if (schema == null) {
145: String err = NULL_ARGUMENT + "; 'schema' must not be null.";
146: throw new IllegalArgumentException(err);
147: }
148:
149: setSchema(schema);
150: setName(name);
151: _attributes = new AttributeGroupDecl(schema);
152: _contentModel = new ContentModelGroupImpl();
153: } //-- Complextype
154:
155: /**
156: * Adds the given AttributeDecl to this ComplexType
157: *
158: * @param attrDecl the AttributeDecl to add to this ComplexType
159: * @exception SchemaException when an AttributeDecl already
160: * exists with the same name as the given AttributeDecl
161: **/
162: public void addAttributeDecl(AttributeDecl attrDecl)
163: throws SchemaException {
164: _attributes.addAttribute(attrDecl);
165:
166: //--set the parent
167: attrDecl.setParent(this );
168: } //-- addAttributeDecl
169:
170: /**
171: * Removes the given AttributeDecl from this ComplexType
172: * @param attrDecl the AttributeDecl to remove.
173: */
174: public void removeAttributeDecl(AttributeDecl attrDecl) {
175: _attributes.removeAttribute(attrDecl);
176: }
177:
178: /**
179: * Adds the given AttributeGroupReference to this ComplexType
180: *
181: * @param attrGroupRef the AttributeGroupReference to add to this
182: * ComplexType
183: **/
184: public void addAttributeGroupReference(
185: AttributeGroupReference attrGroupRef) {
186: _attributes.addReference(attrGroupRef);
187: } //-- addAttributeGroupReference
188:
189: /**
190: * Removes the given AttributeGroupReference from this ComplexType
191: * @param attrGroupRef the AttributeGroupReference to remove.
192: */
193: public void removeAttributeGroupReference(
194: AttributeGroupReference attrGroupRef) {
195: _attributes.removeReference(attrGroupRef);
196: }
197:
198: /**
199: * Creates an AttributeDecl with the given name. The attribute
200: * declaration will still need to be added to this Complextype,
201: * or another archetype in the same schema, by making a call
202: * to #addAttributeDecl
203: * @param name the name of the attribute
204: * @return the new AttributeDecl
205: **/
206: public AttributeDecl createAttributeDecl(String name) {
207: return new AttributeDecl(getSchema(), name);
208: } //-- createAttributeDecl
209:
210: /**
211: * Returns the wilcard used in this complexType (can be null)
212: * @return the wilcard used in this complexType (can be null)
213: */
214: public Wildcard getAnyAttribute() {
215: return _anyAttribute;
216: }
217:
218: /**
219: * Returns the AttributeDecl associated with the given name
220: * @return the AttributeDecl associated with the given name, or
221: * null if no AttributeDecl with the given name was found.
222: **/
223: public AttributeDecl getAttributeDecl(String name) {
224: AttributeDecl result = _attributes.getAttribute(name);
225: return result;
226: } //-- getAttributeDecl
227:
228: /**
229: * Returns an Enumeration of *all* the AttributeDecl objects
230: * declared within this ComplexType. The Enumeration
231: * will contain all AttributeDecl from AttributeGroup
232: * references as well. To return only locally declared
233: * attributes make a call to
234: * <code>getLocalAttributeDecls</code>.
235: *
236: * @return an Enumeration of all the AttributeDecl objects
237: * declared within this Complextype
238: */
239: public Enumeration getAttributeDecls() {
240: return _attributes.getAttributes();
241: } //-- getAttributeDecls
242:
243: /**
244: * Returns an Enumeration of *all* locally defined AttributeDecl
245: * declared within this ComplexType. The Enumeration
246: * will not contain any AttributeDecl from AttributeGroup
247: * references.
248: *
249: * @return an Enumeration of all locally declared AttributeDecl.
250: */
251: public Enumeration getLocalAttributeDecls() {
252: return _attributes.getLocalAttributes();
253: } //-- getLocalAttributeDecls
254:
255: /**
256: * Returns an Enumeration of all the AttributeGroup that are referenced
257: * within this ComplexType.
258: *
259: * @return an Enumeration of all the AttributeGroup that are referenced
260: * within this ComplexType.
261: */
262: public Enumeration getAttributeGroupReferences() {
263: return _attributes.getLocalAttributeGroupReferences();
264: }
265:
266: /**
267: * Returns the base type that this type inherits from.
268: *
269: * @return the base type (also called super type).
270: */
271: public XMLType getBaseType() {
272: if ((_baseType != null) && (super .getBaseType() == null)) {
273: XMLType baseType = getSchema().getType(_baseType);
274: setBaseType(baseType);
275: }
276: return super .getBaseType();
277: } //-- getBaseType
278:
279: /**
280: * Returns the value of the 'block' attribute for this element
281: *
282: * @return the value of the 'block' attribute for this element
283: */
284: public BlockList getBlock() {
285: return _block;
286: } //-- getBlock
287:
288: /**
289: * Returns the content type of this ComplexType.
290: * The Content Type holds the information about the content of the complexType.
291: * For instance, if this complexType is a simpleContent then the simpleType information
292: * will be hold in the content type.
293: *
294: * @return the content type of this ComplexType
295: **/
296: public ContentType getContentType() {
297: return _content;
298: } //-- getContentType
299:
300: /**
301: * Returns the list of values for the final property for this
302: * ComplexType, or null if no final values have been set.
303: *
304: * @return the FinalList for this ComplexType
305: **/
306: public FinalList getFinal() {
307: return _final;
308: } //-- getFinal
309:
310: /**
311: * Returns the parent of this ComplexType, this value may be null if
312: * no parent has been set.
313: *
314: * @return the parent Structure of this ComplexType.
315: **/
316: public Structure getParent() {
317: return _parent;
318: } //-- getParent
319:
320: /**
321: * Returns the Id used to Refer to this Object
322: * @return the Id used to Refer to this Object
323: * @see Referable
324: **/
325: public String getReferenceId() {
326: return "complexType:" + getName();
327: } //-- getReferenceId
328:
329: /**
330: * A helper method that returns true if this complexType
331: * contains an {@literal <any>} element.
332: * @return method that returns true if this complexType
333: * contains an {@literal <any>} element.
334: */
335: public boolean hasAny() {
336: boolean result = false;
337: Enumeration enumeration = _contentModel.enumerate();
338: while (enumeration.hasMoreElements() && !result) {
339: Structure struct = (Structure) enumeration.nextElement();
340: switch (struct.getStructureType()) {
341: case Structure.ELEMENT:
342: break;
343: case Structure.GROUP:
344: case Structure.MODELGROUP:
345: result = ((Group) struct).hasAny();
346: break;
347: case Structure.WILDCARD:
348: result = true;
349: break;
350: default:
351: break;
352: }
353: }
354: return result;
355: }
356:
357: /**
358: * Returns true if this ComplexType has been marked as Abstract.
359: *
360: * @return true if this ComplexType is "abstract".
361: **/
362: public boolean isAbstract() {
363: return _abstract;
364: } //-- isAbstract
365:
366: /**
367: * Returns true if this complexType is a redefinition.
368: *
369: * @return true if this complexType is a redefinition.
370: */
371: public boolean isRedefined() {
372: return _redefinition;
373: }
374:
375: /**
376: * Returns true if this is a top level Complextype
377: * @return true if this is a top level Complextype
378: **/
379: public boolean isTopLevel() {
380: if (getName() == null)
381: return false;
382: if (getSchema() == null)
383: return false;
384: return (getSchema().getComplexType(getName()) == this );
385: } //-- isTopLevel
386:
387: /**
388: * Returns true if this complexType is a 'complexContent'
389: * @return true if this complexType is a 'complexContent'
390: */
391: public boolean isComplexContent() {
392: return _complexContent;
393: }
394:
395: /**
396: * Returns true if this complexType is a 'simpleContent'
397: * @return true if this complexType is a 'simpleContent'
398: */
399: public boolean isSimpleContent() {
400: return (!_complexContent);
401: }
402:
403: /**
404: * Returns true if this complexType is a restriction
405: * @return true if this complexType is a restriction
406: */
407: public boolean isRestricted() {
408: return _restricted;
409: }
410:
411: /**
412: * Sets whether or not this ComplexType should be abstract.
413: *
414: * @param isAbstract a boolean that when true makes this ComplexType
415: * abstract.
416: **/
417: public void setAbstract(boolean isAbstract) {
418: _abstract = isAbstract;
419: } //-- setAbstract
420:
421: /**
422: * Sets the wildcard (anyAttribute) of the complexType
423: * @exception SchemaException thrown when a wildcard as already be set
424: * or when the wildCard is not an {@literal <anyAttribute>}.
425: */
426: public void setAnyAttribute(Wildcard wildcard)
427: throws SchemaException {
428: if (wildcard != null) {
429: if (_anyAttribute != null) {
430: String err = "<anyAttribute> already set in this complexType: "
431: + this .getName();
432: throw new SchemaException(err);
433: }
434:
435: if (!wildcard.isAttributeWildcard()) {
436: String err = "In complexType, " + this .getName()
437: + "the wildcard must be an <anyAttribute>";
438: throw new SchemaException(err);
439: }
440: }
441: _anyAttribute = wildcard;
442: }
443:
444: /**
445: * Removes the given Wildcard from this Group.
446: * @param wildcard the Wildcard to remove.
447: * @return true if the wildcard has been successfully removed, false otherwise.
448: */
449: public boolean removeWildcard(Wildcard wildcard) {
450: if (wildcard == null)
451: return false;
452: if (wildcard.equals(_anyAttribute)) {
453: _anyAttribute = null;
454: return true;
455: }
456: return false;
457:
458: }
459:
460: public void addWildcard(Wildcard wildcard) throws SchemaException {
461: setAnyAttribute(wildcard);
462: }
463:
464: /**
465: * Sets the base type that this type is derived from
466: * @param base the type that this type is derived from
467: **/
468: public void setBase(String base) {
469: _baseType = base;
470: } //-- setBase
471:
472: /**
473: * Sets the base type for this ComplexType
474: *
475: * @param baseType the base type which this ComplexType
476: * extends or restricts
477: */
478: public void setBaseType(XMLType baseType) {
479: super .setBaseType(baseType);
480: if (baseType != null) {
481: if (baseType.isSimpleType()) {
482: _complexContent = false;
483: _content = new SimpleContent((SimpleType) baseType);
484: } else if (baseType.isComplexType()) {
485: ComplexType complexType = (ComplexType) baseType;
486: if (complexType.isSimpleContent()) {
487: _complexContent = false;
488: _content = ((SimpleContent) complexType
489: .getContentType()).copy();
490: } else
491: _complexContent = true;
492: } else {
493: //-- assuming anyType
494: _complexContent = true;
495: }
496: }
497: } //-- setBaseType
498:
499: /**
500: * Sets the value of the 'block' attribute for this ComplexType.
501: *
502: * @param block the value of the block attribute for this
503: * ComplexType definition.
504: **/
505: public void setBlock(BlockList block) {
506:
507: if (block != null) {
508: if (block.hasSubstitution()) {
509: String err = "'substitution' is an illegal value of the "
510: + "'block' attribute for a complexType definition.";
511: throw new IllegalArgumentException(err);
512: }
513: }
514: _block = block;
515: } //-- setBlock
516:
517: /**
518: * Sets the value of the 'block' attribute for this ComplexType.
519: *
520: * @param block the value of the block attribute for this
521: * ComplexType definition.
522: **/
523: public void setBlock(String block) {
524: if (block == null)
525: _block = null;
526: else {
527: setBlock(new BlockList(block));
528: }
529: } //-- setBlock
530:
531: /**
532: * Sets whether or not this complexType is a 'complexContent'
533: * @param complexContent true if this complexType is a 'complexContent'
534: */
535: public void setComplexContent(boolean complexContent) {
536: this ._complexContent = complexContent;
537: }
538:
539: /**
540: * Sets the content type of this complexType.
541: * The Content Type holds the information about the content of the complexType.
542: * For instance, if this complexType is a simpleContent then the simpleType information
543: * will be hold in the content type.
544: * @param contentType the ContentType for this complexType
545: **/
546: public void setContentType(ContentType contentType) {
547: _content = contentType;
548: } //-- setContentType
549:
550: /**
551: * Sets the value of the 'final' attribute for this ComplexType
552: * definition.
553: *
554: * @param finalList the value of the final attribute for this
555: * ComplexType definition.
556: **/
557: public void setFinal(FinalList finalList) {
558: _final = finalList;
559: } //-- setFinal
560:
561: /**
562: * Sets the value of the 'final' attribute for this ComplexType
563: * definition.
564: *
565: * @param finalValue the value of the final attribute for this
566: * ComplexType definition.
567: **/
568: public void setFinal(String finalValue) {
569: if (finalValue == null)
570: _final = null;
571: else
572: _final = new FinalList(finalValue);
573: } //-- setFinal
574:
575: /**
576: * Sets this Group has redefined.
577: */
578: public void setRedefined() {
579: _redefinition = true;
580: }
581:
582: /**
583: * Sets whether or not this complexType is a 'simpleContent'
584: * @param simpleContent true if this complexType is a 'simpleContent'
585: */
586: public void setSimpleContent(boolean simpleContent) {
587: _complexContent = (!simpleContent);
588: }
589:
590: /**
591: * Sets whether or not this complexType is a restriction
592: * @param restricted true if this complexType is a restriction
593: */
594: public void setRestriction(boolean restricted) {
595: this ._restricted = restricted;
596: }
597:
598: public void useResolver(Resolver resolver) {
599: // do nothing for now
600: }
601:
602: //---------------------------------------/
603: //- Implementation of ContentModelGroup -/
604: //---------------------------------------/
605:
606: /**
607: * Adds the given ElementDecl to this ContentModelGroup
608: * @param elementDecl the ElementDecl to add
609: * @exception SchemaException when an ElementDecl already
610: * exists with the same name as the given ElementDecl
611: **/
612: public void addElementDecl(ElementDecl elementDecl)
613: throws SchemaException {
614: _contentModel.addElementDecl(elementDecl);
615:
616: //--set the parent
617: elementDecl.setParent(this );
618: } //-- addElementDecl
619:
620: /**
621: * Removes the given ElementDecl from this ContentModelGroup.
622: * @param element the ElementDecl to remove.
623: * @return true if the element has been successfully removed, false otherwise.
624: */
625: public boolean removeElementDecl(ElementDecl element) {
626: return _contentModel.removeElementDecl(element);
627: }
628:
629: /**
630: * Adds the given Group to this ContentModelGroup
631: * @param group the Group to add
632: * @exception SchemaException when a group with the same name as the
633: * specified group already exists in the current scope
634: **/
635: public void addGroup(Group group) throws SchemaException {
636: _contentModel.addGroup(group);
637:
638: //-- set reference to parent
639: group.setParent(this );
640: } //-- addGroup
641:
642: /**
643: * Removes the given Group from this ContentModelGroup.
644: * @param group the Group to remove.
645: * @return true if the group has been successfully removed, false otherwise.
646: */
647: public boolean removeGroup(Group group) {
648: boolean result = _contentModel.removeGroup(group);
649: group.setParent(null);
650: return result;
651: }
652:
653: /**
654: * Adds the given ModelGroup Definition to this ContentModelGroup
655: * @param group the ModelGroup to add
656: * @exception SchemaException when a group with the same name as the
657: * specified group already exists in the current scope
658: **/
659: public void addGroup(ModelGroup group) throws SchemaException {
660: _contentModel.addGroup(group);
661:
662: //-- set reference to parent
663: group.setParent(this );
664: } //-- addGroup
665:
666: /**
667: * Removes the given ModelGroup Definition from this ContentModelGroup.
668: * @param group the ModelGroup Definition to remove.
669: * @return true if the group has been successfully removed, false otherwise.
670: */
671: public boolean removeGroup(ModelGroup group) {
672: boolean result = _contentModel.removeGroup(group);
673: group.setParent(null);
674: return result;
675: }
676:
677: /**
678: * Returns an enumeration of all the Particles of this
679: * ContentModelGroup
680: *
681: * @return an enumeration of the Particles contained
682: * within this ContentModelGroup
683: **/
684: public Enumeration enumerate() {
685: return _contentModel.enumerate();
686: } //-- enumerate
687:
688: /**
689: * Returns the element declaration with the given name, or null if no
690: * element declaration with that name exists in this ContentModelGroup.
691: *
692: * @param name the name of the element.
693: * @return the ElementDecl with the given name, or null if no
694: * ElementDecl exists in this ContentModelGroup.
695: **/
696: public ElementDecl getElementDecl(String name) {
697: ElementDecl result = _contentModel.getElementDecl(name);
698: return result;
699: } //-- getElementDecl
700:
701: /**
702: * Returns the maximum number of occurances that this ContentModelGroup
703: * may appear
704: * @return the maximum number of occurances that this ContentModelGroup
705: * may appear.
706: * A non positive (n < 1) value indicates that the
707: * value is unspecified (ie. unbounded).
708: **/
709: public int getMaxOccurs() {
710:
711: if (_contentModel.getParticleCount() > 0) {
712: Particle particle = _contentModel.getParticle(0);
713: if (particle instanceof ContentModelGroup) {
714: return particle.getMaxOccurs();
715: }
716: }
717:
718: return _contentModel.getMaxOccurs();
719: } //-- getMaxOccurs
720:
721: /**
722: * Returns the minimum number of occurances that this ContentModelGroup
723: * must appear
724: * @return the minimum number of occurances that this ContentModelGroup
725: * must appear
726: * A negative (n < 0) value indicates that the value is unspecified.
727: **/
728: public int getMinOccurs() {
729: if (_contentModel.getParticleCount() > 0) {
730: Particle particle = _contentModel.getParticle(0);
731: if (particle instanceof ContentModelGroup) {
732: return particle.getMinOccurs();
733: }
734: }
735: return _contentModel.getMinOccurs();
736: } //-- getMinOccurs
737:
738: /**
739: * Returns the Particle at the specified index
740: * @param index the index of the particle to return
741: * @return the CMParticle at the specified index
742: **/
743: public Particle getParticle(int index) {
744: Particle result = _contentModel.getParticle(index);
745: return result;
746: } //-- getParticle
747:
748: /**
749: * Returns the number of particles contained within
750: * this ContentModelGroup
751: *
752: * @return the number of particles
753: **/
754: public int getParticleCount() {
755: return _contentModel.getParticleCount();
756: } //-- getParticleCount
757:
758: //-------------------------------/
759: //- Implementation of Structure -/
760: //-------------------------------/
761:
762: /**
763: * Returns the type of this Schema Structure
764: * @return the type of this Schema Structure
765: **/
766: public short getStructureType() {
767: return Structure.COMPLEX_TYPE;
768: } //-- getStructureType
769:
770: /**
771: * Checks the validity of this ComplexType defintion.
772: *
773: * @throws ValidationException when this ComplexType definition
774: * is invalid.
775: **/
776: public void validate() throws ValidationException {
777: //-- check name
778: if (_parent != null
779: && _parent.getStructureType() != Structure.SCHEMA) {
780: if (getName() != null) {
781: String err = "Only top-level complexTypes can be named.";
782: err += getName() + "is not a valid complexType.";
783: throw new ValidationException(err);
784: }
785: }
786: //-- check attributes
787: _attributes.validate();
788:
789: //-- check content model
790: Enumeration enumeration = _contentModel.enumerate();
791: while (enumeration.hasMoreElements()) {
792: ((Structure) enumeration.nextElement()).validate();
793: }
794:
795: //-- make sure baseType is accessible
796: XMLType type = getBaseType();
797: if ((type == null) && (_baseType != null)) {
798: String error = "The base type '" + _baseType
799: + "' was not found.";
800: throw new ValidationException(error);
801: }
802: if (type != null) {
803: if (type.getStructureType() == Structure.SIMPLE_TYPE) {
804: if (_restricted) {
805: String name = getName();
806: if (name == null) {
807: name = "anonymous-complexType-for-element: ";
808: if (_parent != null) {
809: //-- parent should be an element if name is null, but
810: //-- we'll check the type to be on the safe side
811: if (_parent.getStructureType() == Structure.ELEMENT)
812: name += ((ElementDecl) _parent)
813: .getName();
814: else
815: name += _parent.toString();
816: }
817: }
818: String err = "complexType: " + name;
819: err += "; A complex type cannot be a restriction"
820: + " of a simpleType:";
821: err += type.getName();
822: throw new ValidationException(err);
823: }
824: } else if (type.getStructureType() == Structure.COMPLEX_TYPE) {
825:
826: if (!_complexContent) {
827: //we are now sure that the base is a ComplexType
828: //but is the base of this complexType a simpleType? (see 4.3.3->simpleContent->content type)
829: if (((ComplexType) type).getContentType().getType() != ContentType.SIMPLE) {
830: String name = getName();
831: if (name == null) {
832: name = "anonymous-complexType-for-element: ";
833: if (_parent != null) {
834: //-- parent should be an element if name is null, but
835: //-- we'll check the type to be on the safe side
836: if (_parent.getStructureType() == Structure.ELEMENT)
837: name += ((ElementDecl) _parent)
838: .getName();
839: else
840: name += _parent.toString();
841: }
842: }
843: String err = "complexType: " + name;
844: err += "; When a complexType is a restriction of simpleContent the base type"
845: + " must be a complexType whose base is also simpleContent.";
846: throw new ValidationException(err);
847: }
848: }
849: }
850: }
851:
852: } //-- validate
853:
854: //---------------------/
855: //- Protected Methods -/
856: //---------------------/
857:
858: /**
859: * Sets the parent for this ComplexType
860: *
861: * @param parent the parent Structure for this ComplexType
862: **/
863: protected void setParent(Structure parent) {
864: if (parent != null) {
865: switch (parent.getStructureType()) {
866: case Structure.SCHEMA:
867: case Structure.ELEMENT:
868: break;
869: default:
870: String error = "Invalid parent for ComplexType";
871: throw new IllegalArgumentException(error);
872: }
873: }
874: _parent = parent;
875: } //-- setParent
876:
877: /**
878: * @return true if the content model for this ComplexType is emptiable.
879: */
880: public boolean isEmptiable() {
881: switch (getParticleCount()) {
882: case 0:
883: return true;
884: case 1:
885: Particle p = getParticle(0);
886: if (p.isEmptiable()) {
887: if ((_baseType != null) && !isRestricted()) {
888: // derived by extension
889: XMLType baseType = getBaseType();
890: if ((baseType != null) && baseType.isComplexType()
891: && ((ComplexType) baseType).isEmptiable()) {
892: return true;
893: }
894: } else {
895: // derived by restriction (explicit or shorthand from xs:anyType
896: return true;
897: }
898: }
899: break;
900: }
901: return false;
902: }
903:
904: } //-- Complextype
|