![JAR search and dependency download from the Maven repository](/logo.png)
io.apicurio.datamodels.paths.NodePath Maven / Gradle / Ivy
/*
* Copyright 2022 Red Hat
*
* 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 io.apicurio.datamodels.paths;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Represents a path to a node within the data model. Any node in a data model can be
* represented by its path. The node path can be used to identify and locate a single node
* in the document tree.
* @author [email protected]
*/
public class NodePath {
// Example 1: /foo/bar/baz
// Example 2: /foo/bars[2]/baz
// Example 3: /foo/bars[example]/baz
private final List segments = new LinkedList<>();
public NodePath() {
}
public void append(NodePathSegment segment) {
this.segments.add(segment);
}
public void prepend(NodePathSegment segment) {
this.segments.add(0, segment);
}
public List getSegments() {
return this.segments;
}
public NodePathSegment getLastSegment() {
if (segments.size() > 0) {
return segments.get(segments.size() - 1);
}
return null;
}
@Override
public String toString() {
return toString(false);
}
public String toString(boolean escaped) {
StringBuilder builder = new StringBuilder();
if (this.segments.size() > 0) {
this.segments.forEach(segment -> {
builder.append(segment.toString(escaped));
});
} else {
builder.append("/");
}
return builder.toString();
}
public List toSegments() {
List rval = new ArrayList<>();
for (NodePathSegment segment : segments) {
rval.add(segment.toString());
}
return rval;
}
private static final int SCAN_TYPE_PATH = 0;
private static final int SCAN_TYPE_INDEX = 1;
/**
* Parses a stringified node path and returns an instance. Returns null if
* the path cannot be parsed.
* @param path
*/
public static NodePath parse(String path) {
NodePath rval = null;
if ("/".equals(path)) {
rval = new NodePath();
} else if (path != null && path.indexOf("/") == 0) {
rval = new NodePath();
int currentScanType = SCAN_TYPE_PATH;
int currentIdx = 1;
while (currentIdx < path.length()) {
int segStart = currentIdx;
int segEnd;
if (currentScanType == SCAN_TYPE_PATH) {
int nextPathSep = path.indexOf("/", segStart);
int nextBrace = path.indexOf("[", segStart);
if (nextPathSep == -1) { nextPathSep = path.length(); }
if (nextBrace == -1) { nextBrace = path.length(); }
if (nextPathSep <= nextBrace) {
segEnd = nextPathSep;
} else {
segEnd = nextBrace;
}
} else {
int nextCloseBrace = path.indexOf("]", segStart);
if (nextCloseBrace == -1) { nextCloseBrace = path.length(); }
segEnd = nextCloseBrace + 1;
}
String seg = path.substring(segStart, segEnd);
NodePathSegment segment = NodePathSegment.parse(seg);
rval.append(segment);
// Default next values.
currentScanType = SCAN_TYPE_PATH;
currentIdx = segEnd + 1;
// Find real next values.
if (segEnd >= path.length()) {
// No further scanning - end of input.
} else if (path.charAt(segEnd) == '/') {
currentScanType = SCAN_TYPE_PATH;
currentIdx = segEnd + 1;
} else if (path.charAt(segEnd) == '[') {
currentScanType = SCAN_TYPE_INDEX;
currentIdx = segEnd;
} else if (path.charAt(segEnd) == ']') {
if (path.charAt(segEnd+1) == '[') {
currentScanType = SCAN_TYPE_INDEX;
currentIdx = segEnd + 1;
} else if (path.charAt(segEnd+1) == '/') {
currentScanType = SCAN_TYPE_PATH;
currentIdx = segEnd + 1;
}
}
}
}
return rval;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy