org.conqat.lib.commons.uniformpath.RelativeUniformPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of teamscale-commons Show documentation
Show all versions of teamscale-commons Show documentation
Provides common DTOs for Teamscale
/*
* Copyright (c) CQSE GmbH
*
* 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.conqat.lib.commons.uniformpath;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import org.conqat.lib.commons.collections.CollectionUtils;
import org.conqat.lib.commons.string.StringUtils;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
/**
* A relative uniform path that can be resolved against an absolute uniform
* path. In contrast to absolute uniform paths, relative paths are not typed.
*/
public final class RelativeUniformPath {
/**
* The constituent segments of this uniform path, e.g. for the path
* {@code src/main} this would be the array {@code [src, main]}. Segments may
* consist of dots or be empty.
*/
private final String[] segments;
private RelativeUniformPath(String... pathSegments) {
this(Arrays.asList(pathSegments));
}
private RelativeUniformPath(Iterable pathSegments) {
segments = Iterables.toArray(pathSegments, String.class);
}
/**
* Creates a relative uniform path from the given segments. No resolution of
* relative segments (such as {@code ../src}) is attempted at this stage.
*
* @see #of(List)
*/
public static RelativeUniformPath of(String... segments) {
Preconditions.checkNotNull(segments, UniformPath.SEGMENTS_LIST_MAY_NOT_BE_NULL);
return of(Arrays.asList(segments));
}
/**
* Creates a relative uniform path from the given segments. No resolution of
* relative segments (such as {@code ../src}) is attempted at this stage.
*/
public static RelativeUniformPath of(List segments) {
Preconditions.checkNotNull(segments, UniformPath.SEGMENTS_LIST_MAY_NOT_BE_NULL);
for (String segment : segments) {
UniformPath.checkSegmentValidity(segment, segments, Objects::isNull, "empty segment");
UniformPath.checkSegmentValidity(segment, segments, UniformPath::containsUnescapedSlash,
"contains unescaped slash");
}
if (segments.isEmpty()) {
return new RelativeUniformPath();
}
return new RelativeUniformPath(segments);
}
/**
* Resolves relative path segments such as (such as {@code src/main/../java}) to
* the absolute segments of the path (e.g. {@code [src, java]}).
*/
/* package */ static List resolveRelativeSegments(List pathSegments) {
List canonicalSegments = CollectionUtils.filter(pathSegments,
segment -> !(StringUtils.isEmpty(segment) || segment.equals(".")));
ListIterator canonicalSegmentsIterator = canonicalSegments.listIterator();
while (canonicalSegmentsIterator.hasNext()) {
if (canonicalSegmentsIterator.next().equals("..")) {
// Remove both previous element and the ".." item
canonicalSegmentsIterator.previous();
canonicalSegmentsIterator.remove();
if (!canonicalSegmentsIterator.hasPrevious()) {
throw new IllegalArgumentException(
"Invalid path (refers outside the root folder): " + String.join("/", pathSegments));
}
canonicalSegmentsIterator.previous();
canonicalSegmentsIterator.remove();
}
}
return canonicalSegments;
}
/** Returns a read-only view of the segments of this relative uniform path. */
public List getSegments() {
return Collections.unmodifiableList(Arrays.asList(segments));
}
/** Returns the name of the last segment of this path. */
public String getLastSegment() {
if (segments.length == 0) {
throw new IllegalArgumentException("Cannot get the last segment of the root path");
}
return segments[segments.length - 1];
}
/**
* Creates a new {@link RelativeUniformPath} by prepending the given suffixes to
* the relative uniform path.
*/
public RelativeUniformPath addSuffix(String... suffix) {
String[] newSegments = Arrays.copyOf(segments, segments.length + suffix.length);
System.arraycopy(suffix, 0, newSegments, segments.length, suffix.length);
return RelativeUniformPath.of(newSegments);
}
/**
* Resolves this relative path against the given absolute path, performing path
* canonicalization in the process (i.e. ".." will be resolved to parent
* segment).
*/
public UniformPath resolveAgainstAbsolutePath(UniformPath uniformPath) {
return uniformPath.resolve(this);
}
@Override
public String toString() {
return String.join("/", segments);
}
@Override
public int hashCode() {
return Arrays.hashCode(segments);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof RelativeUniformPath)) {
return false;
}
RelativeUniformPath other = (RelativeUniformPath) obj;
return Arrays.equals(segments, other.segments);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy