001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.impl.xs;
019:
020: import org.apache.xerces.impl.xs.util.XSObjectListImpl;
021: import org.apache.xerces.xs.XSConstants;
022: import org.apache.xerces.xs.XSNamespaceItem;
023: import org.apache.xerces.xs.XSObjectList;
024: import org.apache.xerces.xs.XSParticle;
025: import org.apache.xerces.xs.XSTerm;
026:
027: /**
028: * Store schema particle declaration.
029: *
030: * @xerces.internal
031: *
032: * @author Sandy Gao, IBM
033: *
034: * @version $Id: XSParticleDecl.java 446734 2006-09-15 20:51:23Z mrglavas $
035: */
036: public class XSParticleDecl implements XSParticle {
037:
038: // types of particles
039: public static final short PARTICLE_EMPTY = 0;
040: public static final short PARTICLE_ELEMENT = 1;
041: public static final short PARTICLE_WILDCARD = 2;
042: public static final short PARTICLE_MODELGROUP = 3;
043: public static final short PARTICLE_ZERO_OR_MORE = 4;
044: public static final short PARTICLE_ZERO_OR_ONE = 5;
045: public static final short PARTICLE_ONE_OR_MORE = 6;
046:
047: // type of the particle
048: public short fType = PARTICLE_EMPTY;
049:
050: // term of the particle
051: // for PARTICLE_ELEMENT : the element decl
052: // for PARTICLE_WILDCARD: the wildcard decl
053: // for PARTICLE_MODELGROUP: the model group
054: public XSTerm fValue = null;
055:
056: // minimum occurrence of this particle
057: public int fMinOccurs = 1;
058: // maximum occurrence of this particle
059: public int fMaxOccurs = 1;
060: // optional annotation
061: public XSObjectList fAnnotations = null;
062:
063: // clone this decl
064: public XSParticleDecl makeClone() {
065: XSParticleDecl particle = new XSParticleDecl();
066: particle.fType = fType;
067: particle.fMinOccurs = fMinOccurs;
068: particle.fMaxOccurs = fMaxOccurs;
069: particle.fDescription = fDescription;
070: particle.fValue = fValue;
071: particle.fAnnotations = fAnnotations;
072: return particle;
073: }
074:
075: /**
076: * 3.9.6 Schema Component Constraint: Particle Emptiable
077: * whether this particle is emptible
078: */
079: public boolean emptiable() {
080: return minEffectiveTotalRange() == 0;
081: }
082:
083: // whether this particle contains nothing
084: public boolean isEmpty() {
085: if (fType == PARTICLE_EMPTY)
086: return true;
087: if (fType == PARTICLE_ELEMENT || fType == PARTICLE_WILDCARD)
088: return false;
089:
090: return ((XSModelGroupImpl) fValue).isEmpty();
091: }
092:
093: /**
094: * 3.8.6 Effective Total Range (all and sequence) and
095: * Effective Total Range (choice)
096: * The following methods are used to return min/max range for a particle.
097: * They are not exactly the same as it's described in the spec, but all the
098: * values from the spec are retrievable by these methods.
099: */
100: public int minEffectiveTotalRange() {
101: if (fType == XSParticleDecl.PARTICLE_EMPTY) {
102: return 0;
103: }
104: if (fType == PARTICLE_MODELGROUP) {
105: return ((XSModelGroupImpl) fValue).minEffectiveTotalRange()
106: * fMinOccurs;
107: }
108: return fMinOccurs;
109: }
110:
111: public int maxEffectiveTotalRange() {
112: if (fType == XSParticleDecl.PARTICLE_EMPTY) {
113: return 0;
114: }
115: if (fType == PARTICLE_MODELGROUP) {
116: int max = ((XSModelGroupImpl) fValue)
117: .maxEffectiveTotalRange();
118: if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
119: return SchemaSymbols.OCCURRENCE_UNBOUNDED;
120: if (max != 0
121: && fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)
122: return SchemaSymbols.OCCURRENCE_UNBOUNDED;
123: return max * fMaxOccurs;
124: }
125: return fMaxOccurs;
126: }
127:
128: /**
129: * get the string description of this particle
130: */
131: private String fDescription = null;
132:
133: public String toString() {
134: if (fDescription == null) {
135: StringBuffer buffer = new StringBuffer();
136: appendParticle(buffer);
137: if (!(fMinOccurs == 0 && fMaxOccurs == 0 || fMinOccurs == 1
138: && fMaxOccurs == 1)) {
139: buffer.append("{").append(fMinOccurs);
140: if (fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED)
141: buffer.append("-UNBOUNDED");
142: else if (fMinOccurs != fMaxOccurs)
143: buffer.append("-").append(fMaxOccurs);
144: buffer.append("}");
145: }
146: fDescription = buffer.toString();
147: }
148: return fDescription;
149: }
150:
151: /**
152: * append the string description of this particle to the string buffer
153: * this is for error message.
154: */
155: void appendParticle(StringBuffer buffer) {
156: switch (fType) {
157: case PARTICLE_EMPTY:
158: buffer.append("EMPTY");
159: break;
160: case PARTICLE_ELEMENT:
161: buffer.append(fValue.toString());
162: break;
163: case PARTICLE_WILDCARD:
164: buffer.append('(');
165: buffer.append(fValue.toString());
166: buffer.append(')');
167: break;
168: case PARTICLE_MODELGROUP:
169: buffer.append(fValue.toString());
170: break;
171: }
172: }
173:
174: public void reset() {
175: fType = PARTICLE_EMPTY;
176: fValue = null;
177: fMinOccurs = 1;
178: fMaxOccurs = 1;
179: fDescription = null;
180: fAnnotations = null;
181: }
182:
183: /**
184: * Get the type of the object, i.e ELEMENT_DECLARATION.
185: */
186: public short getType() {
187: return XSConstants.PARTICLE;
188: }
189:
190: /**
191: * The <code>name</code> of this <code>XSObject</code> depending on the
192: * <code>XSObject</code> type.
193: */
194: public String getName() {
195: return null;
196: }
197:
198: /**
199: * The namespace URI of this node, or <code>null</code> if it is
200: * unspecified. defines how a namespace URI is attached to schema
201: * components.
202: */
203: public String getNamespace() {
204: return null;
205: }
206:
207: /**
208: * {min occurs} determines the minimum number of terms that can occur.
209: */
210: public int getMinOccurs() {
211: return fMinOccurs;
212: }
213:
214: /**
215: * {max occurs} whether the maxOccurs value is unbounded.
216: */
217: public boolean getMaxOccursUnbounded() {
218: return fMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED;
219: }
220:
221: /**
222: * {max occurs} determines the maximum number of terms that can occur.
223: */
224: public int getMaxOccurs() {
225: return fMaxOccurs;
226: }
227:
228: /**
229: * {term} One of a model group, a wildcard, or an element declaration.
230: */
231: public XSTerm getTerm() {
232: return fValue;
233: }
234:
235: /**
236: * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
237: */
238: public XSNamespaceItem getNamespaceItem() {
239: return null;
240: }
241:
242: /**
243: * Optional. Annotations.
244: */
245: public XSObjectList getAnnotations() {
246: return (fAnnotations != null) ? fAnnotations
247: : XSObjectListImpl.EMPTY_LIST;
248: }
249:
250: } // class XSParticleDecl
|