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

cdc.util.rdb.RdbElementPath Maven / Gradle / Ivy

package cdc.util.rdb;

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

import cdc.util.lang.Checks;

/**
 * Path associated to an element.
 * 

* For elements that can have siblings with same name (e.g., data type, function or procedure), * a Path, as currently defined, can be ambiguous. * * @author Damien Carbonne * */ public final class RdbElementPath implements Comparable { private final Part[] parts; public static final char KIND_SEPARATOR = ':'; public static final char PART_SEPARATOR = '/'; public static final class Part { private final RdbElementKind kind; private final String name; Part(RdbElementKind kind, String name) { this.kind = kind; this.name = name; } Part(RdbElement element) { this.kind = element.getKind(); this.name = element.getName(); } public RdbElementKind getKind() { return kind; } public String getName() { return name; } @Override public int hashCode() { return kind.hashCode() + 31 * name.hashCode(); } @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof Part)) { return false; } final Part other = (Part) object; return kind == other.kind && name.equals(other.name); } @Override public String toString() { return "[" + kind + ":" + name + "]"; } } RdbElementPath(RdbElement element) { this.parts = new Part[element.getDepth()]; int index = parts.length; RdbElement iter = element; while (iter != null) { index--; this.parts[index] = new Part(iter); iter = iter.getParent(); } } private RdbElementPath(RdbElementPath path, int length) { this.parts = new Part[length]; for (int index = 0; index < length; index++) { this.parts[index] = path.parts[index]; } } public RdbElementPath(RdbElementKind kind, String s) { Checks.isNotNull(kind, "kind"); Checks.isNotNull(s, "s"); // Extract names final List names = new ArrayList<>(); int from = 0; // Number of part separators int seps = 0; while (from < s.length()) { final int to = s.indexOf(PART_SEPARATOR, from); if (to < 0) { names.add(s.substring(from)); from = s.length(); } else { names.add(s.substring(from, to)); from = to + 1; seps++; } } if (seps == names.size()) { names.add(""); } // Build parts if (kind.getDepth() == names.size()) { this.parts = new Part[names.size()]; RdbElementKind k = kind; for (int index = parts.length - 1; index >= 0; index--) { final Part part = new Part(k, names.get(index)); this.parts[index] = part; k = k.getParent(); } } else { throw new IllegalArgumentException("Invalid number of parts " + names.size() + " for " + kind + ", expecting " + kind.getDepth() + " in '" + s + "'"); } } public RdbElementPath(String s) { this(getKind(s), getPath(s)); } private static RdbElementKind getKind(String s) { Checks.isNotNull(s, "s"); final int pos = s.indexOf(KIND_SEPARATOR); if (pos < 0) { throw new IllegalArgumentException("Invalid path '" + s + "', missing '" + KIND_SEPARATOR + "'"); } try { return RdbElementKind.valueOf(s.substring(0, pos)); } catch (final IllegalArgumentException e) { throw new IllegalArgumentException("Invalid path '" + s + "', can not decode '" + s.substring(0, pos) + "'"); } } private static String getPath(String s) { Checks.isNotNull(s, "s"); final int pos = s.indexOf(KIND_SEPARATOR); if (pos < 0) { throw new IllegalArgumentException("Invalid path '" + s + "', missing '" + KIND_SEPARATOR + "'"); } else { return s.substring(pos + 1); } } public int getLength() { return parts.length; } public Part[] getParts() { return parts; } public Part getPart(int index) { return parts[index]; } public RdbElementKind getKind() { return parts[parts.length - 1].getKind(); } public boolean hasPart(RdbElementKind kind) { Checks.isNotNull(kind, "kind"); final int index = kind.getDepth() - 1; return index < parts.length && parts[index].getKind() == kind; } public Part getPart(RdbElementKind kind) { Checks.isNotNull(kind, "kind"); final int index = kind.getDepth() - 1; final Part part = index < parts.length ? parts[index] : null; return part != null && part.getKind() == kind ? part : null; } public RdbElementPath getParent() { if (getLength() == 1) { return null; } else { return new RdbElementPath(this, getLength() - 1); } } @Override public int hashCode() { return Arrays.hashCode(parts); } @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof RdbElementPath)) { return false; } final RdbElementPath other = (RdbElementPath) object; return Arrays.equals(parts, other.parts); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(getKind().name()); builder.append(KIND_SEPARATOR); for (int index = 0; index < getLength(); index++) { if (index > 0) { builder.append(PART_SEPARATOR); } builder.append(getPart(index).getName()); } return builder.toString(); } @Override public int compareTo(RdbElementPath other) { return toString().compareTo(other.toString()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy