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