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.dtd;
019:
020: import org.apache.xerces.xni.grammars.XMLGrammarDescription;
021: import org.apache.xerces.xni.XMLResourceIdentifier;
022: import org.apache.xerces.xni.parser.XMLInputSource;
023:
024: import org.apache.xerces.util.XMLResourceIdentifierImpl;
025: import java.util.Vector;
026:
027: /**
028: * All information specific to DTD grammars.
029: *
030: * @xerces.internal
031: *
032: * @author Neil Graham, IBM
033: * @version $Id: XMLDTDDescription.java 446755 2006-09-15 21:56:27Z mrglavas $
034: */
035: public class XMLDTDDescription extends XMLResourceIdentifierImpl
036: implements org.apache.xerces.xni.grammars.XMLDTDDescription {
037:
038: // Data
039:
040: // pieces of information needed to make this usable as a Grammar key
041: // if we know the root of this grammar, here's its name:
042: protected String fRootName = null;
043:
044: // if we don't know the root name, this stores all elements that
045: // could serve; fPossibleRoots and fRootName cannot both be non-null
046: protected Vector fPossibleRoots = null;
047:
048: // Constructors:
049: public XMLDTDDescription(XMLResourceIdentifier id, String rootName) {
050: this .setValues(id.getPublicId(), id.getLiteralSystemId(), id
051: .getBaseSystemId(), id.getExpandedSystemId());
052: this .fRootName = rootName;
053: this .fPossibleRoots = null;
054: } // init(XMLResourceIdentifier, String)
055:
056: public XMLDTDDescription(String publicId, String literalId,
057: String baseId, String expandedId, String rootName) {
058: this .setValues(publicId, literalId, baseId, expandedId);
059: this .fRootName = rootName;
060: this .fPossibleRoots = null;
061: } // init(String, String, String, String, String)
062:
063: public XMLDTDDescription(XMLInputSource source) {
064: this .setValues(source.getPublicId(), null, source
065: .getBaseSystemId(), source.getSystemId());
066: this .fRootName = null;
067: this .fPossibleRoots = null;
068: } // init(XMLInputSource)
069:
070: // XMLGrammarDescription methods
071:
072: public String getGrammarType() {
073: return XMLGrammarDescription.XML_DTD;
074: } // getGrammarType(): String
075:
076: /**
077: * @return the root name of this DTD or null if root name is unknown
078: */
079: public String getRootName() {
080: return fRootName;
081: } // getRootName(): String
082:
083: /** Set the root name **/
084: public void setRootName(String rootName) {
085: fRootName = rootName;
086: fPossibleRoots = null;
087: }
088:
089: /** Set possible roots **/
090: public void setPossibleRoots(Vector possibleRoots) {
091: fPossibleRoots = possibleRoots;
092: }
093:
094: /**
095: * Compares this grammar with the given grammar. Currently, we compare
096: * as follows:
097: * - if grammar type not equal return false immediately
098: * - try and find a common root name:
099: * - if both have roots, use them
100: * - else if one has a root, examine other's possible root's for a match;
101: * - else try all combinations
102: * - test fExpandedSystemId and fPublicId as above
103: *
104: * @param desc The description of the grammar to be compared with
105: * @return True if they are equal, else false
106: */
107: public boolean equals(Object desc) {
108: if (!(desc instanceof XMLGrammarDescription))
109: return false;
110: if (!getGrammarType().equals(
111: ((XMLGrammarDescription) desc).getGrammarType())) {
112: return false;
113: }
114: // assume it's a DTDDescription
115: XMLDTDDescription dtdDesc = (XMLDTDDescription) desc;
116: if (fRootName != null) {
117: if ((dtdDesc.fRootName) != null
118: && !dtdDesc.fRootName.equals(fRootName)) {
119: return false;
120: } else if (dtdDesc.fPossibleRoots != null
121: && !dtdDesc.fPossibleRoots.contains(fRootName)) {
122: return false;
123: }
124: } else if (fPossibleRoots != null) {
125: if (dtdDesc.fRootName != null) {
126: if (!fPossibleRoots.contains(dtdDesc.fRootName)) {
127: return false;
128: }
129: } else if (dtdDesc.fPossibleRoots == null) {
130: return false;
131: } else {
132: boolean found = false;
133: for (int i = 0; i < fPossibleRoots.size(); i++) {
134: String root = (String) fPossibleRoots.elementAt(i);
135: found = dtdDesc.fPossibleRoots.contains(root);
136: if (found)
137: break;
138: }
139: if (!found)
140: return false;
141: }
142: }
143: // if we got this far we've got a root match... try other two fields,
144: // since so many different DTD's have roots in common:
145: if (fExpandedSystemId != null) {
146: if (!fExpandedSystemId.equals(dtdDesc.fExpandedSystemId))
147: return false;
148: } else if (dtdDesc.fExpandedSystemId != null)
149: return false;
150: if (fPublicId != null) {
151: if (!fPublicId.equals(dtdDesc.fPublicId))
152: return false;
153: } else if (dtdDesc.fPublicId != null)
154: return false;
155: return true;
156: }
157:
158: /**
159: * Returns the hash code of this grammar
160: * Because our .equals method is so complex, we just return a very
161: * simple hash that might avoid calls to the equals method a bit...
162: * @return The hash code
163: */
164: public int hashCode() {
165: if (fExpandedSystemId != null)
166: return fExpandedSystemId.hashCode();
167: if (fPublicId != null)
168: return fPublicId.hashCode();
169: // give up; hope .equals can handle it:
170: return 0;
171: }
172: } // class XMLDTDDescription
|