org.modeshape.schematic.internal.document.Paths Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modeshape-schematic Show documentation
Show all versions of modeshape-schematic Show documentation
API for storing JSON/BSON documents and JSON Schemas support
The newest version!
/*
* ModeShape (http://www.modeshape.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.modeshape.schematic.internal.document;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.modeshape.schematic.annotation.Immutable;
import org.modeshape.schematic.document.Path;
public class Paths {
protected static final Path EMPTY_PATH = new EmptyPath();
protected static final void notNull( Object value,
String name ) {
if (value == null) throw new IllegalArgumentException("The '" + name + "' argument may not be null");
}
protected static final String notNull( String value,
String name ) {
if (value == null) throw new IllegalArgumentException("The '" + name + "' argument may not be null");
value = value.trim();
return value;
}
public static Path rootPath() {
return EMPTY_PATH;
}
public static Path path( String fieldName ) {
return new SinglePath(notNull(fieldName, "fieldName"));
}
public static Path path( String... fieldNames ) {
notNull(fieldNames, "fieldNames");
switch (fieldNames.length) {
case 0:
return EMPTY_PATH;
case 1:
return new SinglePath(fieldNames[0]);
default:
return new MultiSegmentPath(Arrays.asList(fieldNames));
}
}
public static Path path( List fieldNames ) {
notNull(fieldNames, "fieldNames");
switch (fieldNames.size()) {
case 0:
return EMPTY_PATH;
case 1:
return new SinglePath(fieldNames.get(0));
default:
// make copy so we're guaranteed to be immutable
return new MultiSegmentPath(new ArrayList<>(fieldNames));
}
}
public static Path path( Path path,
String fieldName ) {
notNull(path, "path");
return path.with(notNull(fieldName, "fieldName"));
}
public static Path path( Path path,
String... fieldNames ) {
notNull(path, "path");
notNull(fieldNames, "fieldNames");
if (fieldNames.length == 0) return path;
ArrayList names = new ArrayList<>(path.size() + fieldNames.length);
int i = 0;
for (String name : path) {
names.add(notNull(name, "fieldNames[" + i++ + "]"));
}
for (String name : fieldNames) {
names.add(notNull(name, "fieldNames[" + i++ + "]"));
}
return new MultiSegmentPath(names);
}
public static Path path( Path path,
List fieldNames ) {
notNull(path, "path");
notNull(fieldNames, "fieldNames");
if (fieldNames.isEmpty()) return path;
ArrayList names = new ArrayList<>(path.size() + fieldNames.size());
int i = 0;
for (String name : path) {
names.add(notNull(name, "fieldNames[" + i++ + "]"));
}
for (String name : fieldNames) {
names.add(notNull(name, "fieldNames[" + i++ + "]"));
}
return new MultiSegmentPath(names);
}
@Immutable
protected static final class EmptyPath implements Path {
@Override
public Iterator iterator() {
return new Iterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public String next() {
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public String get( int index ) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0");
}
@Override
public String getLast() {
return null;
}
@Override
public String getFirst() {
return null;
}
@Override
public int size() {
return 0;
}
@Override
public boolean startsWith( Path ancestor ) {
return ancestor.size() == 0;
}
@Override
public Path with( String fieldName ) {
return fieldName != null ? new SinglePath(notNull(fieldName, "fieldName")) : this;
}
@Override
public Path parent() {
return EMPTY_PATH;
}
@Override
public int compareTo( Path that ) {
if (that == this) return 0;
if (that instanceof EmptyPath) return 0;
return 0 - that.size();
}
@Override
public int hashCode() {
return 1;
}
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
if (obj instanceof Path) {
Path that = (Path)obj;
return that.size() == 0;
}
return false;
}
@Override
public String toString() {
return "";
}
}
@Immutable
protected static final class SinglePath implements Path {
private final String fieldName;
protected SinglePath( String fieldName ) {
this.fieldName = fieldName;
}
@Override
public Iterator iterator() {
return new Iterator() {
private boolean done = false;
@Override
public boolean hasNext() {
return !done;
}
@SuppressWarnings( "synthetic-access" )
@Override
public String next() {
done = true;
return fieldName;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public String get( int index ) {
if (index != 0) throw new IndexOutOfBoundsException("Index: " + index + ", Size: 1");
return fieldName;
}
@Override
public String getLast() {
return fieldName;
}
@Override
public String getFirst() {
return fieldName;
}
@Override
public Path with( String fieldName ) {
return Paths.path(this.fieldName, fieldName);
}
@Override
public Path parent() {
return EMPTY_PATH;
}
@Override
public int size() {
return 1;
}
@Override
public int hashCode() {
return fieldName.hashCode();
}
@Override
public int compareTo( Path that ) {
if (that == this) return 0;
int diff = this.size() - that.size();
if (diff != 0) return diff;
return this.fieldName.compareTo(that.get(0));
}
@Override
public boolean startsWith( Path ancestor ) {
return this.equals(ancestor);
}
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
if (obj instanceof SinglePath) {
SinglePath that = (SinglePath)obj;
return this.fieldName.equals(that.fieldName);
}
if (obj instanceof Path) {
Path that = (Path)obj;
if (this.size() != that.size()) return false;
return this.fieldName.equals(that.get(0));
}
return false;
}
@Override
public String toString() {
return fieldName;
}
}
@Immutable
protected static final class MultiSegmentPath implements Path {
private final List fieldNames;
private transient String composite;
protected MultiSegmentPath( List fieldNames ) {
assert fieldNames != null;
assert !fieldNames.isEmpty();
this.fieldNames = fieldNames;
}
@Override
public Iterator iterator() {
final Iterator actualIter = fieldNames.iterator();
return new Iterator() {
@Override
public boolean hasNext() {
return actualIter.hasNext();
}
@Override
public String next() {
return actualIter.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public String get( int index ) {
return fieldNames.get(index);
}
@Override
public String getLast() {
return fieldNames.get(fieldNames.size() - 1);
}
@Override
public String getFirst() {
return fieldNames.get(0);
}
@Override
public int size() {
return fieldNames.size();
}
@Override
public boolean startsWith( Path other ) {
if (other.size() > this.size()) return false;
Iterator thatIter = other.iterator();
Iterator thisIter = this.iterator();
while (thatIter.hasNext() && thisIter.hasNext()) {
if (!thisIter.next().equals(thatIter.next())) return false;
}
return !thatIter.hasNext();
}
@Override
public Path with( String fieldName ) {
fieldName = notNull(fieldName, "fieldName");
List newFieldNames = new ArrayList<>(fieldNames.size() + 1);
newFieldNames.addAll(this.fieldNames);
newFieldNames.add(fieldName);
return new MultiSegmentPath(newFieldNames);
}
@Override
public Path parent() {
if (size() <= 1) return EMPTY_PATH;
List parentFieldNames = this.fieldNames.subList(0, this.fieldNames.size() - 1);
return new MultiSegmentPath(parentFieldNames);
}
@Override
public int hashCode() {
return fieldNames.hashCode();
}
@Override
public int compareTo( Path that ) {
if (that == this) return 0;
int diff = this.size() - that.size();
if (diff != 0) return diff;
Iterator thatIter = that.iterator();
Iterator thisIter = this.iterator();
while (thatIter.hasNext()) {
int value = thisIter.next().compareTo(thatIter.next());
if (value != 0) return value;
}
assert !thisIter.hasNext();
return 0;
}
@Override
public boolean equals( Object obj ) {
if (obj == this) return true;
if (obj instanceof Path) {
Path that = (Path)obj;
if (this.size() != that.size()) return false;
Iterator thatIter = that.iterator();
Iterator thisIter = this.iterator();
while (thatIter.hasNext()) {
if (!thisIter.next().equals(thatIter.next())) return false;
}
assert !thisIter.hasNext();
return true;
}
return false;
}
@Override
public String toString() {
if (composite == null) {
StringBuilder sb = new StringBuilder();
Iterator iter = fieldNames.iterator();
if (iter.hasNext()) {
sb.append(iter.next());
while (iter.hasNext()) {
sb.append('.');
sb.append(iter.next());
}
}
composite = sb.toString();
}
return composite;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy