All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.io.data.paths.Path Maven / Gradle / Ivy

The newest version!
package cdc.io.data.paths;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import cdc.util.lang.Checks;

/**
 * Simple XPath like class.
 * 

* Can only handle relative paths like: foo, foo/bar foo[@bar='fred'], foo/@bar, ... * * @author Damien Carbonne */ public final class Path { private final String text; private final Part[] parts; public Path(String text) { this.text = text == null ? "" : text; this.parts = new Part[getNumParts(this.text)]; buildParts(); } public static Path of(String text) { return new Path(text); } private Path(Part... parts) { Checks.isNotNullOrEmpty(parts, "parts"); this.parts = Arrays.copyOf(parts, parts.length); this.text = buildName(this.parts); } private static Part[] normalize(Part... parts) { final List tmp = new ArrayList<>(); Collections.addAll(tmp, parts); normalize(tmp); final Part[] result = new Part[tmp.size()]; return tmp.toArray(result); } private static void normalize(List parts) { if (parts.isEmpty()) { throw new IllegalArgumentException("Invalid empty parts"); } int index = 1; while (index < parts.size()) { final Part part1 = parts.get(index - 1); final Part part2 = parts.get(index); switch (part2.getType()) { case DOT: // Remove it and don't move parts.remove(index); break; case DOT_DOT: switch (part1.getType()) { case ATTRIBUTE: case ELEMENT: case SELECTOR: // Remove part 1 and part 2 if previous is not .. parts.remove(index); parts.remove(index - 1); index--; if (index == 0) { parts.add(0, Part.DOT); index = 1; } break; case DOT: // Remove part1 (.) parts.remove(index - 1); break; case DOT_DOT: index++; break; default: break; } break; case ATTRIBUTE: case ELEMENT: case SELECTOR: index++; break; default: break; } } if (parts.size() > 1 && parts.get(0).getType() == Part.Type.DOT) { parts.remove(0); } } private static int getNumParts(String code) { int count = 0; for (int index = 0; index < code.length(); index++) { if (code.charAt(index) == '/') { count++; } } return count + 1; } private void buildParts() { int prev = 0; int index = 0; while (prev >= 0) { final int next = text.indexOf('/', prev); final Part part; if (next >= 0) { part = new Part(text.substring(prev, next)); prev = next + 1; } else { part = new Part(text.substring(prev)); prev = -1; } parts[index] = part; index++; } } private static String buildName(Part... parts) { final StringBuilder builder = new StringBuilder(); boolean first = true; for (final Part part : parts) { if (!first) { builder.append('/'); } builder.append(part.getText()); first = false; } return builder.toString(); } public Path normalize() { return new Path(normalize(this.parts)); } public String getText() { return text; } @Deprecated(forRemoval = true, since = "2023-07-14") public String getName() { return getText(); } public Part[] getParts() { return parts; } public Part getPart(int index) { return parts[index]; } public Part getLastPart() { return parts[parts.length - 1]; } public int getLength() { return parts.length; } public Path getParent() { final Part[] tmp = Arrays.copyOf(this.parts, this.parts.length + 1); tmp[tmp.length - 1] = Part.DOT_DOT; return new Path(normalize(tmp)); } public Path getSubPath(int beginIndex, int endIndex) { if (beginIndex < 0 || beginIndex > getLength()) { throw new IllegalArgumentException("Invalid beginIndex (" + this + ", " + beginIndex + ", " + endIndex + ")"); } if (endIndex < beginIndex || endIndex > getLength()) { throw new IllegalArgumentException("Invalid endIndex (" + this + ", " + beginIndex + ", " + endIndex + ")"); } if (beginIndex == endIndex) { return new Path("."); } final Part[] tmp = new Part[endIndex - beginIndex]; for (int index = beginIndex; index < endIndex; index++) { tmp[index - beginIndex] = parts[index]; } return new Path(normalize(tmp)); } @Override public int hashCode() { return text.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof Path)) { return false; } final Path o = (Path) other; return text.equals(o.text); } @Override public String toString() { return text; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy