1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2002,2003-2004 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.impl.xs; 22 23 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 24 import com.sun.org.apache.xerces.internal.xs.XSAnnotation; 25 import com.sun.org.apache.xerces.internal.xs.XSConstants; 26 import com.sun.org.apache.xerces.internal.xs.XSModelGroup; 27 import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; 28 import com.sun.org.apache.xerces.internal.xs.XSObjectList; 29 30 /** 31 * Store schema model group declaration. 32 * 33 * @xerces.internal 34 * 35 * @author Sandy Gao, IBM 36 * 37 */ 38 public class XSModelGroupImpl implements XSModelGroup { 39 40 // types of model groups 41 // REVISIT: can't use same constants as those for particles, because 42 // there are place where the constants are used together. For example, 43 // to check whether the content is an element or a sequence. 44 public static final short MODELGROUP_CHOICE = 101; 45 public static final short MODELGROUP_SEQUENCE = 102; 46 public static final short MODELGROUP_ALL = 103; 47 48 // compositor of the model group 49 public short fCompositor; 50 51 // particles 52 public XSParticleDecl[] fParticles = null; 53 public int fParticleCount = 0; 54 55 // this particle's optional annotations 56 public XSObjectList fAnnotations = null; 57 58 // whether this model group contains nothing 59 public boolean isEmpty() { 60 for (int i = 0; i < fParticleCount; i++) { 61 if (!fParticles[i].isEmpty()) 62 return false; 63 } 64 return true; 65 } 66 67 /** 68 * 3.8.6 Effective Total Range (all and sequence) and 69 * Effective Total Range (choice) 70 * The following methods are used to return min/max range for a particle. 71 * They are not exactly the same as it's described in the spec, but all the 72 * values from the spec are retrievable by these methods. 73 */ 74 public int minEffectiveTotalRange() { 75 if (fCompositor == MODELGROUP_CHOICE) 76 return minEffectiveTotalRangeChoice(); 77 else 78 return minEffectiveTotalRangeAllSeq(); 79 } 80 81 // return the sum of all min values of the particles 82 private int minEffectiveTotalRangeAllSeq() { 83 int total = 0; 84 for (int i = 0; i < fParticleCount; i++) 85 total += fParticles[i].minEffectiveTotalRange(); 86 return total; 87 } 88 89 // return the min of all min values of the particles 90 private int minEffectiveTotalRangeChoice() { 91 int min = 0, one; 92 if (fParticleCount > 0) 93 min = fParticles[0].minEffectiveTotalRange(); 94 95 for (int i = 1; i < fParticleCount; i++) { 96 one = fParticles[i].minEffectiveTotalRange(); 97 if (one < min) 98 min = one; 99 } 100 101 return min; 102 } 103 104 public int maxEffectiveTotalRange() { 105 if (fCompositor == MODELGROUP_CHOICE) 106 return maxEffectiveTotalRangeChoice(); 107 else 108 return maxEffectiveTotalRangeAllSeq(); 109 } 110 111 // if one of the max value of the particles is unbounded, return unbounded; 112 // otherwise return the sum of all max values 113 private int maxEffectiveTotalRangeAllSeq() { 114 int total = 0, one; 115 for (int i = 0; i < fParticleCount; i++) { 116 one = fParticles[i].maxEffectiveTotalRange(); 117 if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED) 118 return SchemaSymbols.OCCURRENCE_UNBOUNDED; 119 total += one; 120 } 121 return total; 122 } 123 124 // if one of the max value of the particles is unbounded, return unbounded; 125 // otherwise return the max of all max values 126 private int maxEffectiveTotalRangeChoice() { 127 int max = 0, one; 128 if (fParticleCount > 0) { 129 max = fParticles[0].maxEffectiveTotalRange(); 130 if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED) 131 return SchemaSymbols.OCCURRENCE_UNBOUNDED; 132 } 133 134 for (int i = 1; i < fParticleCount; i++) { 135 one = fParticles[i].maxEffectiveTotalRange(); 136 if (one == SchemaSymbols.OCCURRENCE_UNBOUNDED) 137 return SchemaSymbols.OCCURRENCE_UNBOUNDED; 138 if (one > max) 139 max = one; 140 } 141 return max; 142 } 143 144 /** 145 * get the string description of this particle 146 */ 147 private String fDescription = null; 148 public String toString() { 149 // REVISIT: Commented code may help to eliminate redundant parentheses (test first before committing) 150 if (fDescription == null) { 151 StringBuffer buffer = new StringBuffer(); 152 if (fCompositor == MODELGROUP_ALL) 153 buffer.append("all("); 154 else //if (fMinOccurs != 1 || fMaxOccurs != 1) 155 buffer.append('('); 156 if (fParticleCount > 0) 157 buffer.append(fParticles[0].toString()); 158 for (int i = 1; i < fParticleCount; i++) { 159 if (fCompositor == MODELGROUP_CHOICE) 160 buffer.append('|'); 161 else 162 buffer.append(','); 163 buffer.append(fParticles[i].toString()); 164 } 165 //if (fCompositor == MODELGROUP_ALL || fMinOccurs != 1 || fMaxOccurs != 1) 166 buffer.append(')'); 167 fDescription = buffer.toString(); 168 } 169 return fDescription; 170 } 171 172 public void reset(){ 173 fCompositor = MODELGROUP_SEQUENCE; 174 fParticles = null; 175 fParticleCount = 0; 176 fDescription = null; 177 fAnnotations = null; 178 } 179 180 /** 181 * Get the type of the object, i.e ELEMENT_DECLARATION. 182 */ 183 public short getType() { 184 return XSConstants.MODEL_GROUP; 185 } 186 187 /** 188 * The <code>name</code> of this <code>XSObject</code> depending on the 189 * <code>XSObject</code> type. 190 */ 191 public String getName() { 192 return null; 193 } 194 195 /** 196 * The namespace URI of this node, or <code>null</code> if it is 197 * unspecified. defines how a namespace URI is attached to schema 198 * components. 199 */ 200 public String getNamespace() { 201 return null; 202 } 203 204 /** 205 * {compositor} One of all, choice or sequence. The valid constants values 206 * are: ALL, CHOICE, SEQUENCE. 207 */ 208 public short getCompositor() { 209 if (fCompositor == MODELGROUP_CHOICE) 210 return XSModelGroup.COMPOSITOR_CHOICE; 211 else if (fCompositor == MODELGROUP_SEQUENCE) 212 return XSModelGroup.COMPOSITOR_SEQUENCE; 213 else 214 return XSModelGroup.COMPOSITOR_ALL; 215 } 216 217 /** 218 * {particles} A list of particles 219 */ 220 public XSObjectList getParticles() { 221 return new XSObjectListImpl(fParticles, fParticleCount); 222 } 223 224 /** 225 * Optional. Annotation. 226 */ 227 public XSAnnotation getAnnotation() { 228 return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null; 229 } 230 231 /** 232 * Optional. Annotations. 233 */ 234 public XSObjectList getAnnotations() { 235 return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST; 236 } 237 238 /** 239 * @see org.apache.xerces.xs.XSObject#getNamespaceItem() 240 */ 241 public XSNamespaceItem getNamespaceItem() { 242 return null; 243 } 244 245 } // class XSModelGroupImpl