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