/** * Copyright 2012 Universitat Pompeu Fabra. * * 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.onexus.resource.api; import java.io.Serializable; import java.util.regex.Pattern; public class ORI implements Serializable { public static final char SEPARATOR = '/'; public static final String ONEXUS_TAG = "?"; private String projectUrl; private String path; public ORI(String ori) { parseString(ori); } public ORI(ORI parentResource, String relativePath) { this.projectUrl = parentResource.projectUrl; this.path = resolveRelativePath(parentResource, relativePath); } public ORI(String projectUrl, String path) { this.projectUrl = projectUrl; this.path = path == null || path.isEmpty() ? null : path; if (projectUrl != null && this.path != null && this.path.charAt(0) != SEPARATOR) { this.path = '/' + this.path; } } public String getProjectUrl() { return projectUrl; } public String getPath() { return path; } public boolean isAbsolute() { return projectUrl != null; } public ORI toAbsolute(ORI parentUri) { ORI absoluteOri = new ORI(getProjectUrl(), getPath()); if (isAbsolute()) { return absoluteOri; } if (path.startsWith(String.valueOf(ORI.SEPARATOR))) { // Relative to project URI absoluteOri.projectUrl = parentUri.getProjectUrl(); absoluteOri.path = path; } else { // Relative URI (../../resorce-name) absoluteOri.projectUrl = parentUri.projectUrl; absoluteOri.path = resolveRelativePath(parentUri, path); } return absoluteOri; } public ORI toRelative(ORI parentUri) { ORI relativeOri = new ORI(projectUrl, path); // Impossible to make it relative if ( parentUri == null || projectUrl == null || !projectUrl.equals(parentUri.projectUrl) ) { return relativeOri; } //TODO resolve paths when parentUri is not a direct parent. Like ( /coco/rico ).toRelative( /coco/bueno ) = ../rico if (parentUri.path != null && path.startsWith(parentUri.path)) { relativeOri.path = path.replace(parentUri.path, ""); } relativeOri.projectUrl = null; return relativeOri; } private static String resolveRelativePath(ORI parent, String relativePath) { if (parent == null || relativePath == null) { return relativePath; } ORI container = parent.getParent(); String relative = ".." + ORI.SEPARATOR; while (relativePath.startsWith(relative)) { container = container.getParent(); relativePath = relativePath.substring(3); } return (container.getPath() == null ? "" : container.getPath()) + SEPARATOR + relativePath; } public ORI getParent() { int sMark = path == null ? -1 : path.lastIndexOf(ORI.SEPARATOR); return new ORI(projectUrl, sMark < 1 ? null : path.substring(0, sMark)); } public boolean isChild(ORI childResource) { if (childResource == null) { return false; } if (!isAbsolute()) { throw new RuntimeException("Impossible to check if '" + childResource + "' is a child of the relative resource '" + toString() + "'"); } if (childResource.path == null) { return false; } if (!projectUrl.equals(childResource.projectUrl)) { return false; } if (path == null) { return childResource.path.lastIndexOf(SEPARATOR) <= 0; } if (!childResource.path.startsWith(path)) { return false; } if (childResource.path.equals(path)) { return false; } int lSep = childResource.path.lastIndexOf(SEPARATOR); return lSep == path.length(); } @Override public String toString() { if (isAbsolute()) { if (path != null) { return projectUrl + ONEXUS_TAG + path.substring(1); } else { return projectUrl; } } else { return path; } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof ORI)) { return false; } ORI ori = (ORI) o; if (projectUrl != null ? !projectUrl.equals(ori.projectUrl) : ori.projectUrl != null) { return false; } if (path != null ? !path.equals(ori.path) : ori.path != null) { return false; } return true; } @Override public int hashCode() { int result = projectUrl != null ? projectUrl.hashCode() : 0; result = 31 * result + (path != null ? path.hashCode() : 0); return result; } private void parseString(String ori) { ori = ori.replaceAll("[\n\t ]", ""); String normalizedOri = ori.trim(); // Convert Windows separator to linux separator normalizedOri = normalizedOri.replaceAll(Pattern.quote("\\"), String.valueOf(SEPARATOR)); // Remove ending separator if exists if (normalizedOri.charAt(normalizedOri.length() - 1) == SEPARATOR) { normalizedOri = normalizedOri.substring(0, normalizedOri.length() - 1); } // Parse the ORI int onx = normalizedOri.indexOf(ONEXUS_TAG); if (onx != -1) { projectUrl = normalizedOri.substring(0, onx); path = SEPARATOR + normalizedOri.substring(onx + 1); } else { if (normalizedOri.contains("://")) { projectUrl = normalizedOri; } else { path = normalizedOri; } } } }