1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4/*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements.  See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License.  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
21package com.sun.org.apache.xerces.internal.impl.dtd.models;
22
23import com.sun.org.apache.xerces.internal.impl.dtd.XMLContentSpec;
24import com.sun.org.apache.xerces.internal.xni.QName;
25
26/**
27 * Content model leaf node.
28 *
29 * @xerces.internal
30 *
31 */
32public class CMLeaf
33    extends CMNode {
34
35    //
36    // Data
37    //
38
39    /** This is the element that this leaf represents. */
40    private QName fElement = new QName();
41
42    /**
43     * Part of the algorithm to convert a regex directly to a DFA
44     * numbers each leaf sequentially. If its -1, that means its an
45     * epsilon node. Zero and greater are non-epsilon positions.
46     */
47    private int fPosition = -1;
48
49    //
50    // Constructors
51    //
52
53    /** Constructs a content model leaf. */
54    public CMLeaf(QName element, int position)  {
55        super(XMLContentSpec.CONTENTSPECNODE_LEAF);
56
57        // Store the element index and position
58        fElement.setValues(element);
59        fPosition = position;
60    }
61
62    /** Constructs a content model leaf. */
63    public CMLeaf(QName element)  {
64        super(XMLContentSpec.CONTENTSPECNODE_LEAF);
65
66        // Store the element index and position
67        fElement.setValues(element);
68    }
69
70    //
71    // Package methods
72    //
73
74    final QName getElement()
75    {
76        return fElement;
77    }
78
79    final int getPosition()
80    {
81        return fPosition;
82    }
83
84    final void setPosition(int newPosition)
85    {
86        fPosition = newPosition;
87    }
88
89    //
90    // CMNode methods
91    //
92
93    // package
94
95    public boolean isNullable()
96    {
97        // Leaf nodes are never nullable unless its an epsilon node
98        return (fPosition == -1);
99    }
100
101    public String toString()
102    {
103        StringBuilder strRet = new StringBuilder(fElement.toString());
104        strRet.append(" (");
105        strRet.append(fElement.uri);
106        strRet.append(',');
107        strRet.append(fElement.localpart);
108        strRet.append(')');
109        if (fPosition >= 0)
110        {
111            strRet.append
112            (
113                " (Pos:"
114                + fPosition
115                + ")"
116            );
117        }
118        return strRet.toString();
119    }
120
121    // protected
122
123    protected void calcFirstPos(CMStateSet toSet)
124    {
125        // If we are an epsilon node, then the first pos is an empty set
126        if (fPosition == -1)
127            toSet.zeroBits();
128
129        // Otherwise, its just the one bit of our position
130        else
131            toSet.setBit(fPosition);
132    }
133
134    protected void calcLastPos(CMStateSet toSet)
135    {
136        // If we are an epsilon node, then the last pos is an empty set
137        if (fPosition == -1)
138            toSet.zeroBits();
139
140        // Otherwise, its just the one bit of our position
141        else
142            toSet.setBit(fPosition);
143    }
144
145} // class CMLeaf
146