blob: 791509a9e03728d74623d5505273264cd09cb8a5 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.hadoop.fs.swift.util;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.swift.exceptions.SwiftConfigurationException;
import org.apache.hadoop.fs.swift.http.RestClientBindings;
import java.net.URI;
import java.util.regex.Pattern;
/**
* Swift hierarchy mapping of (container, path)
*/
public final class SwiftObjectPath {
private static final Pattern PATH_PART_PATTERN = Pattern.compile(".*/AUTH_\\w*/");
/**
* Swift container
*/
private final String container;
/**
* swift object
*/
private final String object;
private final String uriPath;
/**
* Build an instance from a (host, object) pair
*
* @param container container name
* @param object object ref underneath the container
*/
public SwiftObjectPath(String container, String object) {
if (object == null) {
throw new IllegalArgumentException("object name can't be null");
}
this.container = container;
this.object = URI.create(object).getPath();
uriPath = buildUriPath();
}
public String getContainer() {
return container;
}
public String getObject() {
return object;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SwiftObjectPath)) return false;
final SwiftObjectPath that = (SwiftObjectPath) o;
return this.toUriPath().equals(that.toUriPath());
}
@Override
public int hashCode() {
int result = container.hashCode();
result = 31 * result + object.hashCode();
return result;
}
private String buildUriPath() {
return SwiftUtils.joinPaths(container, object);
}
public String toUriPath() {
return uriPath;
}
@Override
public String toString() {
return toUriPath();
}
/**
* Test for the object matching a path, ignoring the container
* value.
*
* @param path path string
* @return true iff the object's name matches the path
*/
public boolean objectMatches(String path) {
return object.equals(path);
}
/**
* Query to see if the possibleChild object is a child path of this.
* object.
*
* The test is done by probing for the path of the this object being
* at the start of the second -with a trailing slash, and both
* containers being equal
*
* @param possibleChild possible child dir
* @return true iff the possibleChild is under this object
*/
public boolean isEqualToOrParentOf(SwiftObjectPath possibleChild) {
String origPath = toUriPath();
String path = origPath;
if (!path.endsWith("/")) {
path = path + "/";
}
String childPath = possibleChild.toUriPath();
return childPath.equals(origPath) || childPath.startsWith(path);
}
/**
* Create a path tuple of (container, path), where the container is
* chosen from the host of the URI.
*
* @param uri uri to start from
* @param path path underneath
* @return a new instance.
* @throws SwiftConfigurationException if the URI host doesn't parse into
* container.service
*/
public static SwiftObjectPath fromPath(URI uri,
Path path)
throws SwiftConfigurationException {
return fromPath(uri, path, false);
}
/**
* Create a path tuple of (container, path), where the container is
* chosen from the host of the URI.
* A trailing slash can be added to the path. This is the point where
* these /-es need to be appended, because when you construct a {@link Path}
* instance, {@link Path#normalizePath(String, String)} is called
* -which strips off any trailing slash.
*
* @param uri uri to start from
* @param path path underneath
* @param addTrailingSlash should a trailing slash be added if there isn't one.
* @return a new instance.
* @throws SwiftConfigurationException if the URI host doesn't parse into
* container.service
*/
public static SwiftObjectPath fromPath(URI uri,
Path path,
boolean addTrailingSlash)
throws SwiftConfigurationException {
String url =
path.toUri().getPath().replaceAll(PATH_PART_PATTERN.pattern(), "");
//add a trailing slash if needed
if (addTrailingSlash && !url.endsWith("/")) {
url += "/";
}
String container = uri.getHost();
if (container == null) {
//no container, not good: replace with ""
container = "";
} else if (container.contains(".")) {
//its a container.service URI. Strip the container
container = RestClientBindings.extractContainerName(container);
}
return new SwiftObjectPath(container, url);
}
}