/* * Copyright 2012 Jakob Külzer * * 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.om.core.api.path; /** * Describes a path. A path has always the following form: * <ul> * <li>Starts with a slash * <li>has zero or more segments, delimited by a slash each * </ul> * * This class is immutable, i.e. instances, once created, cannot be modified. * All methods that modify the path, return a new instance. * * @author Jakob Külzer * */ public class Path { public static final String SLASH = "/"; private final int length; private final String path; public Path(String path) { if (path == null) throw new RuntimeException("Cannot construct path from null"); this.path = cleanPath(path); this.length = calculateLength(); } public Path append(String append) { return new Path(path + SLASH + append); } private int calculateLength() { if (isRoot()) return 0; int counter = 0; for (char c : path.toCharArray()) { if (c == SLASH.charAt(0)) counter++; } return counter; } private String cleanPath(String path) { // Remove whitespace: path = path.trim(); // Remove multiple path delimiters: path = path.replaceAll("//+", "/"); // Remove trailing slash: path = !path.equals(SLASH) && path.length() > 2 && path.endsWith(SLASH) ? path.substring(0, path.length() - 1) : path; return path; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Path other = (Path) obj; if (path == null) { if (other.path != null) return false; } else if (!path.equals(other.path)) return false; return true; } /** * Returns the lenght of this path in segments. If this path only describes * root, this method will return 0. * * @return */ public int getLength() { return length; } public Path getParent() { if (isRoot()) return this; return new Path(path.substring(0, path.lastIndexOf(SLASH) + 1)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((path == null) ? 0 : path.hashCode()); return result; } /** * Retuns true if this path describes only the root. * * @return */ public boolean isRoot() { return path.equals(SLASH); } @Override public String toString() { return path; } }