Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2017 Google Inc.
*
* 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 com.google.firebase.database.core;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.snapshot.ChildKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class Path implements Iterable, Comparable {
private static final Path EMPTY_PATH = new Path("");
private final ChildKey[] pieces;
private final int start;
private final int end;
public Path(ChildKey... segments) {
this.pieces = Arrays.copyOf(segments, segments.length);
this.start = 0;
this.end = segments.length;
for (ChildKey name : segments) {
assert name != null : "Can't construct a path with a null value!";
}
}
public Path(List segments) {
this.pieces = new ChildKey[segments.size()];
int i = 0;
for (String segment : segments) {
this.pieces[i++] = ChildKey.fromString(segment);
}
this.start = 0;
this.end = segments.size();
}
public Path(String pathString) {
String[] segments = pathString.split("/");
int count = 0;
for (String segment : segments) {
if (segment.length() > 0) {
count++;
}
}
pieces = new ChildKey[count];
int j = 0;
for (String segment : segments) {
if (segment.length() > 0) {
pieces[j++] = ChildKey.fromString(segment);
}
}
this.start = 0;
this.end = pieces.length;
}
private Path(ChildKey[] pieces, int start, int end) {
this.pieces = pieces;
this.start = start;
this.end = end;
}
public static Path getRelative(Path from, Path to) {
ChildKey outerFront = from.getFront();
ChildKey innerFront = to.getFront();
if (outerFront == null) {
return to;
} else if (outerFront.equals(innerFront)) {
return getRelative(from.popFront(), to.popFront());
} else {
throw new DatabaseException("INTERNAL ERROR: " + to + " is not contained in " + from);
}
}
public static Path getEmptyPath() {
return EMPTY_PATH;
}
public Path child(Path path) {
int newSize = this.size() + path.size();
ChildKey[] newPieces = new ChildKey[newSize];
System.arraycopy(this.pieces, this.start, newPieces, 0, this.size());
System.arraycopy(path.pieces, path.start, newPieces, this.size(), path.size());
return new Path(newPieces, 0, newSize);
}
public Path child(ChildKey child) {
int size = this.size();
ChildKey[] newPieces = new ChildKey[size + 1];
System.arraycopy(this.pieces, this.start, newPieces, 0, size);
newPieces[size] = child;
return new Path(newPieces, 0, size + 1);
}
@Override
public String toString() {
if (this.isEmpty()) {
return "/";
} else {
StringBuilder builder = new StringBuilder();
for (int i = this.start; i < this.end; i++) {
builder.append("/");
builder.append(pieces[i].asString());
}
return builder.toString();
}
}
public String wireFormat() {
if (this.isEmpty()) {
return "/";
} else {
StringBuilder builder = new StringBuilder();
for (int i = this.start; i < this.end; i++) {
if (i > this.start) {
builder.append("/");
}
builder.append(pieces[i].asString());
}
return builder.toString();
}
}
public List asList() {
List result = new ArrayList<>(this.size());
for (ChildKey key : this) {
result.add(key.asString());
}
return result;
}
public ChildKey getFront() {
if (this.isEmpty()) {
return null;
} else {
return pieces[this.start];
}
}
public Path popFront() {
int newStart = this.start;
if (!this.isEmpty()) {
newStart++;
}
return new Path(pieces, newStart, this.end);
}
public Path getParent() {
if (this.isEmpty()) {
return null;
} else {
return new Path(pieces, start, end - 1);
}
}
public ChildKey getBack() {
if (!this.isEmpty()) {
return pieces[end - 1];
} else {
return null;
}
}
public boolean isEmpty() {
return start >= end;
}
public int size() {
return this.end - this.start;
}
@Override
public Iterator iterator() {
return new Iterator() {
int offset = start;
@Override
public boolean hasNext() {
return offset < end;
}
@Override
public ChildKey next() {
if (!hasNext()) {
throw new NoSuchElementException("No more elements.");
}
ChildKey child = pieces[offset];
offset++;
return child;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Can't remove component from immutable Path!");
}
};
}
public boolean contains(Path other) {
if (this.size() > other.size()) {
return false;
}
int i = this.start;
int j = other.start;
while (i < this.end) {
if (!this.pieces[i].equals(other.pieces[j])) {
return false;
}
i++;
j++;
}
return true;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Path)) {
return false;
}
if (this == other) {
return true;
}
Path otherPath = (Path) other;
if (size() != otherPath.size()) {
return false;
}
for (int i = start, j = otherPath.start; i < end && j < otherPath.end; i++, j++) {
if (!this.pieces[i].equals(otherPath.pieces[j])) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
int hashCode = 0;
for (int i = start; i < end; i++) {
hashCode = hashCode * 37 + pieces[i].hashCode();
}
return hashCode;
}
@Override
public int compareTo(Path other) {
int i;
int j;
for (i = start, j = other.start; i < end && j < other.end; i++, j++) {
int comp = this.pieces[i].compareTo(other.pieces[j]);
if (comp != 0) {
return comp;
}
}
if (i == end && j == other.end) {
return 0;
} else if (i == end) {
return -1;
} else {
return 1;
}
}
}