--- /dev/null
+/*
+ * Copyright 2005 the original author or authors.
+ *
+ * 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.wamblee.photos.model;
+
+import java.io.Serializable;
+
+/**
+ * Represents a path to a photo.
+ *
+ */
+public class Path implements Serializable {
+
+ static final long serialVersionUID = 1287597039089552731L;
+
+ /**
+ * The parts of the path.
+ */
+ private String[] _path;
+
+ /**
+ * Constructs an empty path.
+ *
+ */
+ public Path() {
+ _path = new String[0];
+ }
+
+ /**
+ * Construcst the path based on a path string.
+ * @param aPath Path, must start with a /
+ */
+ public Path(String aPath) {
+ if ( aPath == null ) {
+ throw new IllegalArgumentException("path is null");
+ }
+ if ( !aPath.startsWith("/")) {
+ throw new IllegalArgumentException("path must start with / '" + aPath + "'");
+ }
+ if ( aPath.length() == 1 ) {
+ _path = new String[0];
+ return;
+ }
+ _path = aPath.substring(1).split("/");
+ }
+
+ /**
+ * Constructs the path based on an array of the parts.
+ * @param aPath Path.
+ */
+ private Path(String[] aPath) {
+ _path = aPath;
+ }
+
+ /**
+ * Returns the child of a path by appending a part.
+ * @param aId Id to append.
+ * @return Child.
+ * @throws IllegalArgumentException In case the id contains a /
+ */
+ public Path child(String aId) {
+ if ( aId.matches("/")) {
+ throw new IllegalArgumentException("Id '" + aId + "' contains a /");
+ }
+ String[] newpath = new String[_path.length + 1];
+ System.arraycopy(_path, 0, newpath, 0, _path.length);
+ newpath[_path.length] = aId;
+ return new Path(newpath);
+ }
+
+ /**
+ * Checks if the path is the root path.
+ * @return True if the path is the root.
+ */
+ public boolean isRoot() {
+ return _path.length == 0;
+ }
+
+ /**
+ * Gets the parent of the path.
+ * @return Parent of the path or the root if the path is already at the root.
+ */
+ public Path parent() {
+ if ( isRoot() ) {
+ return this;
+ }
+ String[] newpath = new String[_path.length -1];
+ System.arraycopy(_path, 0, newpath, 0, _path.length - 1);
+ return new Path(newpath);
+ }
+
+ /**
+ * Converts the path to a regular path.
+ * @return A path, always starting with a /
+ */
+ public String toString() {
+ if ( _path.length == 0 ) {
+ return "/";
+ }
+ String result = "";
+ for (String part: _path) {
+ result += "/" + part;
+ }
+ return result;
+ }
+
+ /**
+ * Gets the id (last part) of the path.
+ * @return Id or null if the path has no parts (root)
+ */
+ public String getId() {
+ if ( _path.length == 0 ) {
+ return null;
+ }
+ return _path[_path.length -1];
+ }
+
+ /**
+ * Returns the number of components in the path.
+ * @return Size.
+ */
+ public int size() {
+ return _path.length;
+ }
+
+ /**
+ * Returns a part of the path.
+ * @param aPart Part number (starts at 0).
+ * @return Part.
+ */
+ public String getPart(int aPart) {
+ return _path[aPart];
+ }
+
+ /**
+ * Strips the first part of the path and returns the remainder.
+ * @return Remainder.
+ */
+ public Path remainder() {
+ if ( _path.length == 0 ) {
+ return null;
+ }
+ String[] result = new String[_path.length-1];
+ for (int i = 0; i < _path.length-1; i++) {
+ result[i] = _path[i+1];
+ }
+ return new Path(result);
+ }
+}