You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2005/06/01 16:51:23 UTC
svn commit: r179383 - in
/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core:
PathMap.java lock/LockInfo.java lock/LockManagerImpl.java
lock/LockToken.java lock/PathMap.java
Author: dpfister
Date: Wed Jun 1 07:51:23 2005
New Revision: 179383
URL: http://svn.apache.org/viewcvs?rev=179383&view=rev
Log:
Moved PathMap to core package
Added:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java (with props)
Removed:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/PathMap.java
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockInfo.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockToken.java
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java?rev=179383&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java Wed Jun 1 07:51:23 2005
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.apache.jackrabbit.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Generic path map that associates information with the individual path elements
+ * of a path.
+ */
+public class PathMap {
+
+ /**
+ * Root element
+ */
+ private final Child root = new Child(Path.ROOT.getNameElement());
+
+ /**
+ * Map a path to a child. If <code>exact</code> is <code>false</code>,
+ * returns the last available item along the path that is stored in the map.
+ * @param path path to map
+ * @param exact flag indicating whether an exact match is required
+ * @return child, maybe <code>null</code> if <code>exact</code> is
+ * <code>true</code>
+ */
+ public Child map(Path path, boolean exact) {
+ Path.PathElement[] elements = path.getElements();
+ Child current = root;
+
+ for (int i = 1; i < elements.length; i++) {
+ Child next = current.getChild(elements[i], false);
+ if (next == null) {
+ if (exact) {
+ return null;
+ }
+ break;
+ }
+ current = next;
+ }
+ return current;
+ }
+
+ /**
+ * Create a child given by its path. The path map will create any necessary
+ * intermediate children.
+ * @param path path to child
+ * @param obj object to store at destination
+ */
+ public Child put(Path path, Object obj) {
+ Child child = put(path);
+ child.obj = obj;
+ return child;
+ }
+
+ /**
+ * Create an empty child given by its path.
+ * @param path path to child
+ */
+ public Child put(Path path) {
+ Path.PathElement[] elements = path.getElements();
+ Child current = root;
+
+ for (int i = 1; i < elements.length; i++) {
+ current = current.getChild(elements[i], true);
+ }
+ return current;
+ }
+
+ /**
+ * Ressurrect a child previously removed, given by its path and the
+ * child structure. If an item at path already exists, nothing happens.
+ * @param path new path to child
+ * @param zombie previously removed child object to store at destination
+ */
+ public void resurrect(Path path, Child zombie) {
+ Path.PathElement[] elements = path.getElements();
+ Path.PathElement name = path.getNameElement();
+ Child parent = root;
+
+ if (map(path, true) == null) {
+ for (int i = 1; i < elements.length - 1; i++) {
+ parent = parent.getChild(elements[i], true);
+ }
+ parent.setChild(name, zombie);
+ }
+ }
+
+ /**
+ * Traverse the path map and call back requester.
+ * @param includeEmpty if <code>true</code> invoke call back on every child
+ * regardless, whether the associated object is empty
+ * or not; otherwise call back on non-empty children
+ * only
+ */
+ public void traverse(ChildVisitor visitor, boolean includeEmpty) {
+ root.traverse(visitor, includeEmpty);
+ }
+
+ /**
+ * Internal class holding the object associated with a certain
+ * path element.
+ */
+ public static class Child {
+
+ /**
+ * Parent child
+ */
+ private Child parent;
+
+ /**
+ * Map of immediate children of this child.
+ */
+ private Map children;
+
+ /**
+ * Number of non-null children
+ */
+ private int childrenCount;
+
+ /**
+ * Object associated with this child
+ */
+ private Object obj;
+
+ /**
+ * QName associated with this child
+ */
+ private QName name;
+
+ /**
+ * index associated with this child
+ */
+ private int index;
+
+ /**
+ * Create a new instance of this class with a path element.
+ * @param element path element of this child
+ */
+ Child(Path.PathElement element) {
+ this.name = element.getName();
+ this.index = element.getIndex();
+ }
+
+ /**
+ * Create a new instance of this class.
+ */
+ Child() {
+ }
+
+ /**
+ * Insert an empty child. Will shift all children having an index
+ * greater than or equal to the child inserted to the right.
+ * @param element child's path element
+ */
+ public void insertChild(Path.PathElement element) {
+ int index = getOneBasedIndex(element) - 1;
+ if (children != null) {
+ ArrayList list = (ArrayList) children.get(element.getName());
+ if (list != null && list.size() > index) {
+ for (int i = index; i < list.size(); i++) {
+ Child child = (Child) list.get(i);
+ if (child != null) {
+ child.index++;
+ }
+ }
+ list.add(index, null);
+ }
+ }
+ }
+
+ /**
+ * Remove a child. Will shift all children having an index greater than
+ * the child removed to the left.
+ * @param element child's path element
+ * @return removed child, may be <code>null</code>
+ */
+ public Child removeChild(Path.PathElement element) {
+ int index = getOneBasedIndex(element) - 1;
+ if (children != null) {
+ ArrayList list = (ArrayList) children.get(element.getName());
+ if (list != null && list.size() > index) {
+ for (int i = index + 1; i < list.size(); i++) {
+ Child child = (Child) list.get(i);
+ if (child != null) {
+ child.index--;
+ }
+ }
+ Child child = (Child) list.remove(index);
+ if (child != null) {
+ child.parent = null;
+ childrenCount--;
+ }
+ if (obj == null && childrenCount == 0) {
+ remove();
+ }
+ return child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a child matching a path element. If a child does not exist
+ * at that position and <code>create</code> is <code>true</code> a
+ * new child will be created.
+ * @param element child's path element
+ * @param create flag indicating whether this child should be
+ * created if not available
+ */
+ private Child getChild(Path.PathElement element, boolean create) {
+ int index = getOneBasedIndex(element) - 1;
+ Child child = null;
+
+ if (children != null) {
+ ArrayList list = (ArrayList) children.get(element.getName());
+ if (list != null && list.size() > index) {
+ child = (Child) list.get(index);
+ }
+ }
+ if (child == null && create) {
+ child = new Child();
+ setChild(element, child);
+ }
+ return child;
+ }
+
+ /**
+ * Add a child.
+ * @param element child's path element
+ * @param child child to add
+ */
+ private void setChild(Path.PathElement element, Child child) {
+ int index = getOneBasedIndex(element) - 1;
+ if (children == null) {
+ children = new HashMap();
+ }
+ ArrayList list = (ArrayList) children.get(element.getName());
+ if (list == null) {
+ list = new ArrayList();
+ children.put(element.getName(), list);
+ }
+ while (list.size() < index) {
+ list.add(null);
+ }
+ if (list.size() == index) {
+ list.add(child);
+ } else {
+ list.set(index, child);
+ }
+
+ child.parent = this;
+ child.name = element.getName();
+ child.index = element.getIndex();
+
+ childrenCount++;
+ }
+
+ /**
+ * Remove this child. Delegates the call to the parent item.
+ */
+ public void remove() {
+ if (parent != null) {
+ parent.removeChild(getPathElement());
+ }
+ }
+
+ /**
+ * Return the object associated with this child
+ * @return object associated with this child
+ */
+ public Object get() {
+ return obj;
+ }
+
+ /**
+ * Set the object associated with this child
+ * @param obj object associated with this child
+ */
+ public void set(Object obj) {
+ this.obj = obj;
+
+ if (obj == null && childrenCount == 0) {
+ remove();
+ }
+ }
+
+ /**
+ * Return the name of this child
+ * @return name
+ */
+ public QName getName() {
+ return name;
+ }
+
+ /**
+ * Return the index of this child
+ * @return index
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ /**
+ * Return a path element pointing to this child
+ * @return path element
+ */
+ public Path.PathElement getPathElement() {
+ return Path.create(name, index).getNameElement();
+ }
+
+ /**
+ * Return the path of this element.
+ * @return path
+ * @throws MalformedPathException if building the path fails
+ */
+ public Path getPath() throws MalformedPathException {
+ if (parent == null) {
+ return Path.ROOT;
+ }
+
+ Path.PathBuilder builder = new Path.PathBuilder();
+ getPath(builder);
+ return builder.getPath();
+ }
+
+ /**
+ * Internal implementation of {@link #getPath()} that populates entries
+ * in a builder. On exit, <code>builder</code> contains the path
+ * of this element
+ */
+ private void getPath(Path.PathBuilder builder) {
+ if (parent == null) {
+ builder.addRoot();
+ return;
+ }
+ parent.getPath(builder);
+ if (index == 0 || index == 1) {
+ builder.addLast(name);
+ } else {
+ builder.addLast(name, index);
+ }
+ }
+
+ /**
+ * Checks whether this child has the specified path. Introduced to
+ * avoid catching a <code>MalformedPathException</code> for simple
+ * path comparisons.
+ * @param path path to compare to
+ * @return <code>true</code> if this child has the path
+ * <code>path</code>, <code>false</code> otherwise
+ */
+ public boolean hasPath(Path path) {
+ return hasPath(path.getElements(), path.getLength());
+ }
+
+ /**
+ * Checks whether this child has the specified path, given by
+ * path elements.
+ * @param elements path elements to compare to
+ * @param len number of elements to compare to
+ * @return <code>true</code> if this child has the path given;
+ * otherwise <code>false</code>
+ */
+ private boolean hasPath(Path.PathElement[] elements, int len) {
+ if (getPathElement().equals(elements[len - 1])) {
+ if (parent != null) {
+ return parent.hasPath(elements, len - 1);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return 1-based index of a path element.
+ */
+ private static int getOneBasedIndex(Path.PathElement element) {
+ int index = element.getIndex();
+ if (index == 0) {
+ return 1;
+ } else {
+ return index;
+ }
+ }
+
+ /**
+ * Recursively invoked traversal method.
+ * @param visitor visitor to invoke
+ * @param includeEmpty if <code>true</code> invoke call back on every
+ * child regardless, whether the associated object is empty
+ * or not; otherwise call back on non-empty children only
+ */
+ public void traverse(ChildVisitor visitor, boolean includeEmpty) {
+ if (children != null) {
+ Iterator iter = children.values().iterator();
+ while (iter.hasNext()) {
+ ArrayList list = (ArrayList) iter.next();
+ for (int i = 0; i < list.size(); i++) {
+ Child child = (Child) list.get(i);
+ if (child != null) {
+ child.traverse(visitor, includeEmpty);
+ }
+ }
+ }
+ }
+ if (includeEmpty || obj != null) {
+ visitor.childVisited(this);
+ }
+ }
+
+ /**
+ * Return the depth of this child. Defined to be <code>0</code> for the
+ * root node and <code>n + 1</code> for some child if the depth of its
+ * parent is <code>n</code>.
+ */
+ public int getDepth() {
+ if (parent != null) {
+ return parent.getDepth() + 1;
+ }
+ return 0;
+ }
+
+ /**
+ * Return a flag indicating whether the specified node is a
+ * child of this node.
+ * @param other node to check
+ */
+ public boolean isAncestorOf(Child other) {
+ Child parent = other.parent;
+ while (parent != null) {
+ if (parent == this) {
+ return true;
+ }
+ parent = parent.parent;
+ }
+ return false;
+ }
+
+ /**
+ * Return the parent of this child
+ * @return parent or <code>null</code> if this is the root node
+ */
+ public Child getParent() {
+ return parent;
+ }
+ }
+
+ /**
+ * Child visitor used in {@link PathMap#traverse}
+ */
+ public interface ChildVisitor {
+
+ /**
+ * Invoked for every child visited on a tree traversal
+ * @param child child visited
+ */
+ void childVisited(Child child);
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PathMap.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockInfo.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockInfo.java?rev=179383&r1=179382&r2=179383&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockInfo.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockInfo.java Wed Jun 1 07:51:23 2005
@@ -27,7 +27,7 @@
/**
* Contains information about a lock and gets placed inside the child
- * information of a {@link PathMap}.
+ * information of a {@link org.apache.jackrabbit.core.PathMap}.
*/
class LockInfo implements SessionListener {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=179383&r1=179382&r2=179383&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Wed Jun 1 07:51:23 2005
@@ -24,6 +24,7 @@
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.MalformedPathException;
+import org.apache.jackrabbit.core.PathMap;
import org.apache.jackrabbit.core.observation.SynchronousEventListener;
import org.apache.jackrabbit.core.observation.EventImpl;
import org.apache.log4j.Logger;
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockToken.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockToken.java?rev=179383&r1=179382&r2=179383&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockToken.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/lock/LockToken.java Wed Jun 1 07:51:23 2005
@@ -93,7 +93,10 @@
}
}
- int rem = 37 - (result % 37);
+ int rem = result % 37;
+ if (rem != 0) {
+ rem = 37 - rem;
+ }
if (rem >= 0 && rem <= 9) {
return (char) ('0' + rem);
} else if (rem >= 10 && rem <= 35) {