1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2005 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 package com.sun.org.apache.xerces.internal.xpointer; 21 22 import com.sun.org.apache.xerces.internal.impl.Constants; 23 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; 24 import com.sun.org.apache.xerces.internal.util.SymbolTable; 25 import com.sun.org.apache.xerces.internal.xni.Augmentations; 26 import com.sun.org.apache.xerces.internal.xni.QName; 27 import com.sun.org.apache.xerces.internal.xni.XMLAttributes; 28 import com.sun.org.apache.xerces.internal.xni.XNIException; 29 import com.sun.org.apache.xerces.internal.xs.AttributePSVI; 30 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 31 32 /** 33 * <p> 34 * Implements the XPointerPart interface and handles processing of 35 * ShortHand Pointers. It identifies at most one element in the 36 * resource's information set; specifically, the first one (if any) 37 * in document order that has a matching NCName as an identifier. 38 * </p> 39 * 40 * 41 */ 42 class ShortHandPointer implements XPointerPart { 43 44 // The name of the ShortHand pointer 45 private String fShortHandPointer; 46 47 // The name of the ShortHand pointer 48 private boolean fIsFragmentResolved = false; 49 50 // SymbolTable 51 private SymbolTable fSymbolTable; 52 53 // 54 // Constructors 55 // 56 public ShortHandPointer() { 57 } 58 59 public ShortHandPointer(SymbolTable symbolTable) { 60 fSymbolTable = symbolTable; 61 } 62 63 /** 64 * The XPointerProcessor takes care of this. Simply set the ShortHand Pointer here. 65 * 66 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#parseXPointer(java.lang.String) 67 */ 68 public void parseXPointer(String part) throws XNIException { 69 fShortHandPointer = part; 70 // reset fIsFragmentResolved 71 fIsFragmentResolved = false; 72 } 73 74 /** 75 * Resolves the XPointer ShortHand pointer based on the rules defined in 76 * Section 3.2 of the XPointer Framework Recommendation. 77 * Note that in the current implementation only supports DTD determined ID's. 78 * 79 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#resolveXPointer(com.sun.org.apache.xerces.internal.xni.QName, com.sun.org.apache.xerces.internal.xni.XMLAttributes, com.sun.org.apache.xerces.internal.xni.Augmentations, int event) 80 */ 81 int fMatchingChildCount = 0; 82 public boolean resolveXPointer(QName element, XMLAttributes attributes, 83 Augmentations augs, int event) throws XNIException { 84 85 // reset fIsFragmentResolved 86 if (fMatchingChildCount == 0) { 87 fIsFragmentResolved = false; 88 } 89 90 // On startElement or emptyElement, if no matching elements or parent 91 // elements were found, check for a matching idenfitier. 92 if (event == XPointerPart.EVENT_ELEMENT_START) { 93 if (fMatchingChildCount == 0) { 94 fIsFragmentResolved = hasMatchingIdentifier(element, attributes, augs, 95 event); 96 } 97 if (fIsFragmentResolved) { 98 fMatchingChildCount++; 99 } 100 } else if (event == XPointerPart.EVENT_ELEMENT_EMPTY) { 101 if (fMatchingChildCount == 0) { 102 fIsFragmentResolved = hasMatchingIdentifier(element, attributes, augs, 103 event); 104 } 105 } 106 else { 107 // On endElement, decrease the matching child count if the child or 108 // its parent was resolved. 109 if (fIsFragmentResolved) { 110 fMatchingChildCount--; 111 } 112 } 113 114 return fIsFragmentResolved ; 115 } 116 117 /** 118 * 119 * @param element 120 * @param attributes 121 * @param augs 122 * @param event 123 * @return 124 * @throws XNIException 125 */ 126 private boolean hasMatchingIdentifier(QName element, 127 XMLAttributes attributes, Augmentations augs, int event) 128 throws XNIException { 129 String normalizedValue = null; 130 131 // The identifiers of an element are determined by the 132 // ShortHand Pointer as follows: 133 134 if (attributes != null) { 135 for (int i = 0; i < attributes.getLength(); i++) { 136 137 // 1. If an element information item has an attribute information item 138 // among its [attributes] that is a schema-determined ID, then it is 139 // identified by the value of that attribute information item's 140 // [schema normalized value] property; 141 normalizedValue = getSchemaDeterminedID(attributes, i); 142 if (normalizedValue != null) { 143 break; 144 } 145 146 // 2. If an element information item has an element information item among 147 // its [children] that is a schema-determined ID, then it is identified by 148 // the value of that element information item's [schema normalized value] property; 149 // ??? 150 normalizedValue = getChildrenSchemaDeterminedID(attributes, i); 151 if (normalizedValue != null) { 152 break; 153 } 154 155 // 3. If an element information item has an attribute information item among 156 // its [attributes] that is a DTD-determined ID, then it is identified by the 157 // value of that attribute information item's [normalized value] property. 158 // An attribute information item is a DTD-determined ID if and only if it has 159 // a [type definition] property whose value is equal to ID. 160 normalizedValue = getDTDDeterminedID(attributes, i); 161 if (normalizedValue != null) { 162 break; 163 } 164 // 4. No externally determined ID's 165 } 166 } 167 168 if (normalizedValue != null 169 && normalizedValue.equals(fShortHandPointer)) { 170 return true; 171 } 172 173 return false; 174 } 175 176 /** 177 * Rerturns the DTD determine-ID 178 * 179 * @param attributes 180 * @param index 181 * @return String 182 * @throws XNIException 183 */ 184 public String getDTDDeterminedID(XMLAttributes attributes, int index) 185 throws XNIException { 186 187 if (attributes.getType(index).equals("ID")) { 188 return attributes.getValue(index); 189 } 190 return null; 191 } 192 193 /** 194 * Returns the schema-determined-ID. 195 * 196 * 197 * @param attributes 198 * @param index 199 * @return A String containing the schema-determined ID. 200 * @throws XNIException 201 */ 202 public String getSchemaDeterminedID(XMLAttributes attributes, int index) 203 throws XNIException { 204 Augmentations augs = attributes.getAugmentations(index); 205 AttributePSVI attrPSVI = (AttributePSVI) augs 206 .getItem(Constants.ATTRIBUTE_PSVI); 207 208 if (attrPSVI != null) { 209 // An element or attribute information item is a schema-determined 210 // ID if and only if one of the following is true:] 211 212 // 1. It has a [member type definition] or [type definition] property 213 // whose value in turn has [name] equal to ID and [target namespace] 214 // equal to http://www.w3.org/2001/XMLSchema; 215 216 // 2. It has a [base type definition] whose value has that [name] and [target namespace]; 217 218 // 3. It has a [base type definition] whose value has a [base type definition] 219 // whose value has that [name] and [target namespace], and so on following 220 // the [base type definition] property recursively; 221 222 XSTypeDefinition typeDef = attrPSVI.getMemberTypeDefinition(); 223 if (typeDef != null) { 224 typeDef = attrPSVI.getTypeDefinition(); 225 } 226 227 // 228 if (typeDef != null && ((XSSimpleType) typeDef).isIDType()) { 229 return attrPSVI.getSchemaNormalizedValue(); 230 } 231 232 // 4 & 5 NA 233 } 234 235 return null; 236 } 237 238 /** 239 * Not quite sure how this can be correctly implemented. 240 * 241 * @param attributes 242 * @param index 243 * @return String - We return null since we currenly do not supprt this. 244 * @throws XNIException 245 */ 246 public String getChildrenSchemaDeterminedID(XMLAttributes attributes, 247 int index) throws XNIException { 248 return null; 249 } 250 251 /** 252 * 253 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#isFragmentResolved() 254 */ 255 public boolean isFragmentResolved() { 256 return fIsFragmentResolved; 257 } 258 259 /** 260 * 261 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#isChildFragmentResolved() 262 */ 263 public boolean isChildFragmentResolved() { 264 return fIsFragmentResolved & ( fMatchingChildCount > 0); 265 } 266 267 /** 268 * Returns the name of the ShortHand pointer 269 * 270 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#getSchemeName() 271 */ 272 public String getSchemeName() { 273 return fShortHandPointer; 274 } 275 276 /** 277 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#getSchemeData() 278 */ 279 public String getSchemeData() { 280 return null; 281 } 282 283 /** 284 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#setSchemeName(java.lang.String) 285 */ 286 public void setSchemeName(String schemeName) { 287 fShortHandPointer = schemeName; 288 } 289 290 /** 291 * @see com.sun.org.apache.xerces.internal.xpointer.XPointerPart#setSchemeData(java.lang.String) 292 */ 293 public void setSchemeData(String schemeData) { 294 // NA 295 } 296 }