001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.graph.property.basic;
025
026 import net.jcip.annotations.Immutable;
027 import org.jboss.dna.common.text.TextEncoder;
028 import org.jboss.dna.graph.property.Name;
029 import org.jboss.dna.graph.property.NamespaceRegistry;
030 import org.jboss.dna.graph.property.Path;
031
032 /**
033 * A basic implementation of {@link Path.Segment}.
034 *
035 * @author Randall Hauch
036 */
037 @Immutable
038 public class BasicPathSegment implements Path.Segment {
039
040 /**
041 */
042 private static final long serialVersionUID = 4367349287846075157L;
043 private final Name name;
044 private final int index;
045
046 /**
047 * @param name the segment name
048 * @throws IllegalArgumentException if the name is null or if the index is invalid
049 */
050 public BasicPathSegment( Name name ) {
051 assert name != null;
052 this.name = name;
053 this.index = Path.DEFAULT_INDEX;
054 }
055
056 /**
057 * @param name the segment name
058 * @param index the segment index
059 * @throws IllegalArgumentException if the name is null or if the index is invalid
060 */
061 public BasicPathSegment( Name name,
062 int index ) {
063 assert name != null;
064 assert index >= Path.DEFAULT_INDEX;
065 this.name = name;
066 this.index = (this.isSelfReference() || this.isParentReference()) ? Path.DEFAULT_INDEX : index;
067 }
068
069 /**
070 * {@inheritDoc}
071 */
072 public int getIndex() {
073 return this.index;
074 }
075
076 /**
077 * {@inheritDoc}
078 */
079 public Name getName() {
080 return this.name;
081 }
082
083 /**
084 * {@inheritDoc}
085 */
086 public boolean hasIndex() {
087 return this.index != Path.DEFAULT_INDEX;
088 }
089
090 /**
091 * {@inheritDoc}
092 */
093 public boolean isParentReference() {
094 return this.name.getLocalName().equals(Path.PARENT) && this.name.getNamespaceUri().length() == 0;
095 }
096
097 /**
098 * {@inheritDoc}
099 */
100 public boolean isSelfReference() {
101 return this.name.getLocalName().equals(Path.SELF) && this.name.getNamespaceUri().length() == 0;
102 }
103
104 /**
105 * {@inheritDoc}
106 */
107 public int compareTo( Path.Segment that ) {
108 if (this == that) return 0;
109 int diff = this.getName().compareTo(that.getName());
110 if (diff != 0) return diff;
111 return this.getIndex() - that.getIndex();
112 }
113
114 /**
115 * {@inheritDoc}
116 */
117 @Override
118 public int hashCode() {
119 return this.name.hashCode();
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 @Override
126 public boolean equals( Object obj ) {
127 if (obj == this) return true;
128 if (obj instanceof Path.Segment) {
129 Path.Segment that = (Path.Segment)obj;
130 if (!this.getName().equals(that.getName())) return false;
131 return Math.abs(getIndex()) == Math.abs(that.getIndex());
132 }
133 return false;
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 @Override
140 public String toString() {
141 if (this.hasIndex()) {
142 return this.getName().toString() + "[" + this.getIndex() + "]";
143 }
144 return this.getName().toString();
145 }
146
147 /**
148 * {@inheritDoc}
149 */
150 public String getUnencodedString() {
151 return getString(Path.NO_OP_ENCODER);
152 }
153
154 /**
155 * {@inheritDoc}
156 */
157 public String getString() {
158 return getString(Path.DEFAULT_ENCODER);
159 }
160
161 /**
162 * {@inheritDoc}
163 */
164 public String getString( TextEncoder encoder ) {
165 if (encoder == null) encoder = Path.DEFAULT_ENCODER;
166 String encodedName = this.getName().getString(encoder);
167 if (this.hasIndex()) {
168 return encodedName + "[" + this.getIndex() + "]";
169 }
170 return encodedName;
171 }
172
173 /**
174 * {@inheritDoc}
175 */
176 public String getString( NamespaceRegistry namespaceRegistry ) {
177 return getString(namespaceRegistry, Path.DEFAULT_ENCODER);
178 }
179
180 /**
181 * {@inheritDoc}
182 */
183 public String getString( NamespaceRegistry namespaceRegistry,
184 TextEncoder encoder ) {
185 return getString(namespaceRegistry, encoder, null);
186 }
187
188 /**
189 * {@inheritDoc}
190 *
191 * @see org.jboss.dna.graph.property.Path.Segment#getString(org.jboss.dna.graph.property.NamespaceRegistry,
192 * org.jboss.dna.common.text.TextEncoder, org.jboss.dna.common.text.TextEncoder)
193 */
194 public String getString( NamespaceRegistry namespaceRegistry,
195 TextEncoder encoder,
196 TextEncoder delimiterEncoder ) {
197 if (encoder == null) encoder = Path.DEFAULT_ENCODER;
198 String encodedName = this.getName().getString(namespaceRegistry, encoder, delimiterEncoder);
199 if (this.hasIndex()) {
200 return encodedName + "[" + this.getIndex() + "]";
201 }
202 return encodedName;
203 }
204 }