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.models;
019:
020: import org.apache.xerces.impl.dtd.XMLContentSpec;
021: import org.apache.xerces.xni.QName;
022:
023: /**
024: * Content model leaf node.
025: *
026: * @xerces.internal
027: *
028: * @version $Id: CMLeaf.java 572057 2007-09-02 18:03:20Z mrglavas $
029: */
030: public class CMLeaf extends CMNode {
031:
032: //
033: // Data
034: //
035:
036: /** This is the element that this leaf represents. */
037: private final QName fElement = new QName();
038:
039: /**
040: * Part of the algorithm to convert a regex directly to a DFA
041: * numbers each leaf sequentially. If its -1, that means its an
042: * epsilon node. Zero and greater are non-epsilon positions.
043: */
044: private int fPosition = -1;
045:
046: //
047: // Constructors
048: //
049:
050: /** Constructs a content model leaf. */
051: public CMLeaf(QName element, int position) {
052: super (XMLContentSpec.CONTENTSPECNODE_LEAF);
053:
054: // Store the element index and position
055: fElement.setValues(element);
056: fPosition = position;
057: }
058:
059: /** Constructs a content model leaf. */
060: public CMLeaf(QName element) {
061: super (XMLContentSpec.CONTENTSPECNODE_LEAF);
062:
063: // Store the element index and position
064: fElement.setValues(element);
065: }
066:
067: //
068: // Package methods
069: //
070:
071: final QName getElement() {
072: return fElement;
073: }
074:
075: final int getPosition() {
076: return fPosition;
077: }
078:
079: final void setPosition(int newPosition) {
080: fPosition = newPosition;
081: }
082:
083: //
084: // CMNode methods
085: //
086:
087: // package
088:
089: public boolean isNullable() {
090: // Leaf nodes are never nullable unless its an epsilon node
091: return (fPosition == -1);
092: }
093:
094: public String toString() {
095: StringBuffer strRet = new StringBuffer(fElement.toString());
096: strRet.append(" (");
097: strRet.append(fElement.uri);
098: strRet.append(',');
099: strRet.append(fElement.localpart);
100: strRet.append(')');
101: if (fPosition >= 0) {
102: strRet.append(" (Pos:").append(Integer.toString(fPosition))
103: .append(')');
104: }
105: return strRet.toString();
106: }
107:
108: // protected
109:
110: protected void calcFirstPos(CMStateSet toSet) {
111: // If we are an epsilon node, then the first pos is an empty set
112: if (fPosition == -1)
113: toSet.zeroBits();
114:
115: // Otherwise, its just the one bit of our position
116: else
117: toSet.setBit(fPosition);
118: }
119:
120: protected void calcLastPos(CMStateSet toSet) {
121: // If we are an epsilon node, then the last pos is an empty set
122: if (fPosition == -1)
123: toSet.zeroBits();
124:
125: // Otherwise, its just the one bit of our position
126: else
127: toSet.setBit(fPosition);
128: }
129:
130: } // class CMLeaf
|