You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/09/09 18:28:03 UTC
svn commit: r995483 - in /jackrabbit/trunk/jackrabbit-spi-commons/src:
main/java/org/apache/jackrabbit/spi/commons/name/
test/java/org/apache/jackrabbit/spi/commons/name/
Author: jukka
Date: Thu Sep 9 16:28:02 2010
New Revision: 995483
URL: http://svn.apache.org/viewvc?rev=995483&view=rev
Log:
JCR-2744: Avoid element arrays in PathImpl
Use the new path element classes to replace the inner classes in PathFactoryImpl.
Modified:
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameElement.java
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java
jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/ElementTest.java
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameElement.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameElement.java?rev=995483&r1=995482&r2=995483&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameElement.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameElement.java Thu Sep 9 16:28:02 2010
@@ -28,6 +28,26 @@ final class NameElement extends Abstract
/** Serial version UID */
private static final long serialVersionUID = -6655583285077651379L;
+ /** Static cache of instances of this class. */
+ private static final HashCache cache = new HashCache();
+
+ /**
+ * Creates and returns a named path element. A cache of path elements
+ * with an unspecified index is used to avoid having too many instances
+ * of this class in memory.
+ *
+ * @param element the element to return from the cache
+ * @return the given element or a previously cached copy
+ */
+ public static NameElement create(Name name, int index) {
+ NameElement element = new NameElement(name, index);
+ if (index == Path.INDEX_UNDEFINED) {
+ return (NameElement) cache.get(element);
+ } else {
+ return element;
+ }
+ }
+
/**
* Name of the path element.
*/
@@ -46,7 +66,7 @@ final class NameElement extends Abstract
* @param name name of this element
* @param index index of this element, or {@link Path#INDEX_UNDEFINED}
*/
- public NameElement(Name name, int index) {
+ private NameElement(Name name, int index) {
if (name != null && index >= 0) {
this.index = index;
this.name = name;
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java?rev=995483&r1=995482&r2=995483&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java Thu Sep 9 16:28:02 2010
@@ -43,18 +43,17 @@ public class PathFactoryImpl implements
private final static Name PARENT_NAME = NAME_FACTORY.create(Name.NS_DEFAULT_URI, PARENT_LITERAL);
private final static Name ROOT_NAME = NAME_FACTORY.create(Name.NS_DEFAULT_URI, "");
- private static final Path.Element CURRENT_ELEMENT = new SpecialElement(CURRENT_NAME);
- private static final Path.Element PARENT_ELEMENT = new SpecialElement(PARENT_NAME);
- private static final Path.Element ROOT_ELEMENT = new SpecialElement(ROOT_NAME);
-
/**
* the root path
*/
- private static final Path ROOT = new PathImpl(new Path.Element[]{ROOT_ELEMENT}, true);
- private static final Path CURRENT_PATH = new PathImpl(new Path.Element[]{CURRENT_ELEMENT}, true);
- private static final Path PARENT_PATH = new PathImpl(new Path.Element[]{PARENT_ELEMENT}, true);
+ private static final Path ROOT =
+ new PathImpl(new Path.Element[] { RootElement.INSTANCE }, true);
+
+ private static final Path CURRENT_PATH =
+ new PathImpl(new Path.Element[] { CurrentElement.INSTANCE }, true);
- private final HashCache ELEMENT_CACHE = new HashCache();
+ private static final Path PARENT_PATH =
+ new PathImpl(new Path.Element[] { ParentElement.INSTANCE }, true);
private PathFactoryImpl() {}
@@ -193,13 +192,13 @@ public class PathFactoryImpl implements
if (name == null) {
throw new IllegalArgumentException("name must not be null");
} else if (name.equals(PARENT_NAME)) {
- return PARENT_ELEMENT;
+ return ParentElement.INSTANCE;
} else if (name.equals(CURRENT_NAME)) {
- return CURRENT_ELEMENT;
+ return CurrentElement.INSTANCE;
} else if (name.equals(ROOT_NAME)) {
- return ROOT_ELEMENT;
+ return RootElement.INSTANCE;
} else {
- return getCachedElement(new Element(name, Path.INDEX_UNDEFINED));
+ return NameElement.create(name, Path.INDEX_UNDEFINED);
}
}
@@ -219,7 +218,7 @@ public class PathFactoryImpl implements
"Special path elements (root, '.' and '..') can not have an explicit index: "
+ name + "[" + index + "]");
} else {
- return new Element(name, index);
+ return NameElement.create(name, index);
}
}
@@ -239,11 +238,11 @@ public class PathFactoryImpl implements
throw new IllegalArgumentException("null PathElement literal");
}
if (elementString.equals(ROOT_NAME.toString())) {
- return ROOT_ELEMENT;
+ return RootElement.INSTANCE;
} else if (elementString.equals(CURRENT_LITERAL)) {
- return CURRENT_ELEMENT;
+ return CurrentElement.INSTANCE;
} else if (elementString.equals(PARENT_LITERAL)) {
- return PARENT_ELEMENT;
+ return ParentElement.INSTANCE;
} else if (elementString.startsWith("[") && elementString.endsWith("]") && elementString.length() > 2) {
return new IdentifierElement(elementString.substring(1, elementString.length()-1));
}
@@ -251,7 +250,7 @@ public class PathFactoryImpl implements
int pos = elementString.indexOf('[');
if (pos == -1) {
Name name = NAME_FACTORY.create(elementString);
- return getCachedElement(new Element(name, Path.INDEX_UNDEFINED));
+ return NameElement.create(name, Path.INDEX_UNDEFINED);
}
Name name = NAME_FACTORY.create(elementString.substring(0, pos));
int pos1 = elementString.indexOf(']');
@@ -263,7 +262,7 @@ public class PathFactoryImpl implements
if (index < 1) {
throw new IllegalArgumentException("invalid PathElement literal: " + elementString + " (index is 1-based)");
}
- return new Element(name, index);
+ return NameElement.create(name, index);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("invalid PathElement literal: " + elementString + " (" + e.getMessage() + ")");
}
@@ -273,21 +272,21 @@ public class PathFactoryImpl implements
* @see PathFactory#getCurrentElement()
*/
public Path.Element getCurrentElement() {
- return CURRENT_ELEMENT;
+ return CurrentElement.INSTANCE;
}
/**
* @see PathFactory#getParentElement()
*/
public Path.Element getParentElement() {
- return PARENT_ELEMENT;
+ return ParentElement.INSTANCE;
}
/**
* @see PathFactory#getRootElement()
*/
public Path.Element getRootElement() {
- return ROOT_ELEMENT;
+ return RootElement.INSTANCE;
}
/**
@@ -464,7 +463,7 @@ public class PathFactoryImpl implements
*/
int tmp = elems0.length - lengthCommon;
while (tmp-- > 0) {
- l.add(0, PARENT_ELEMENT);
+ l.add(0, ParentElement.INSTANCE);
}
}
// add remainder of other path
@@ -500,7 +499,7 @@ public class PathFactoryImpl implements
System.arraycopy(elements, 0, ancestorElements, 0, elements.length);
for (int i = elements.length; i < ancestorElements.length; i++) {
- ancestorElements[i] = PARENT_ELEMENT;
+ ancestorElements[i] = ParentElement.INSTANCE;
}
return new PathImpl(ancestorElements, false).getNormalizedPath();
}
@@ -712,331 +711,6 @@ public class PathFactoryImpl implements
}
}
- //-------------------------------------------------------< Path.Element >---
-
- /**
- * If a cached copy of the given element already exists, then returns
- * that copy. Otherwise the given element is cached and returned. This
- * method only works correctly with elements that have an undefined index!
- *
- * @param element the element to return from the cache
- * @return the given element or a previously cached copy
- */
- private Element getCachedElement(Element element) {
- assert element.getIndex() == Path.INDEX_UNDEFINED;
- return (Element) ELEMENT_CACHE.get(element);
- }
-
- /**
- * Object representation of a single JCR path element.
- *
- * @see Path.Element
- */
- private static class Element implements Path.Element {
-
- /**
- * Name of the path element.
- */
- private final Name name;
-
- /**
- * Optional index of the path element. Set to zero, if not
- * explicitly specified, otherwise contains the 1-based index.
- */
- private final int index;
-
- /**
- * Private constructor for creating a path element with the given
- * name and index. Instead of using this constructor directly
- * the factory methods {@link PathFactory#createElement(Name)} and
- * {@link PathFactory#create(Name, int)} should be used.
- *
- * @param name A <code>Name</code> object.
- * @param index index
- */
- private Element(Name name, int index) {
- this.index = index;
- this.name = name;
- }
-
- /**
- * @see Path.Element#getName()
- */
- public Name getName() {
- return name;
- }
-
- /**
- * @see Path.Element#getIndex()
- */
- public int getIndex() {
- return index;
- }
-
- /**
- * @see Path.Element#getNormalizedIndex()
- */
- public int getNormalizedIndex() {
- if (index == Path.INDEX_UNDEFINED) {
- return Path.INDEX_DEFAULT;
- } else {
- return index;
- }
- }
-
- /**
- * @return always returns false.
- * @see Path.Element#denotesRoot()
- */
- public boolean denotesRoot() {
- return false;
- }
-
- /**
- * @return always returns false.
- * @see Path.Element#denotesParent()
- */
- public boolean denotesParent() {
- return false;
- }
-
- /**
- * @return always returns false.
- * @see Path.Element#denotesCurrent()
- */
- public boolean denotesCurrent() {
- return false;
- }
-
- /**
- * @return always returns true.
- * @see Path.Element#denotesName()
- */
- public boolean denotesName() {
- return true;
- }
-
- /**
- * @return always returns false.
- * @see Path.Element#denotesIdentifier()
- */
- public boolean denotesIdentifier() {
- return false;
- }
-
- /**
- * @see Path.Element#getString()
- */
- public String getString() {
- return toString();
- }
-
- /**
- * Returns a string representation of this path element. Note that
- * the path element name is expressed using the <code>{uri}name</code>
- * syntax.
- *
- * @return string representation of the path element
- * @see Object#toString()
- */
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- // name
- sb.append(name.toString());
- // index
- if (index > Path.INDEX_DEFAULT) {
- sb.append('[');
- sb.append(index);
- sb.append(']');
- }
- return sb.toString();
- }
-
- /**
- * Computes a hash code for this path element.
- *
- * @return hash code
- * @see Object#hashCode()
- */
- @Override
- public int hashCode() {
- int h = 17;
- h = 37 * h + getNormalizedIndex();
- h = 37 * h + name.hashCode();
- return h;
- }
-
- /**
- * Check for path element equality. Returns true if the given
- * object is a PathElement and contains the same name and index
- * as this one.
- *
- * @param obj the object to compare with
- * @return <code>true</code> if the path elements are equal
- * @see Object#equals(Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof Path.Element) {
- Path.Element other = (Path.Element) obj;
- return name.equals(other.getName())
- && getNormalizedIndex() == other.getNormalizedIndex();
- }
- return false;
- }
- }
-
- /**
- * Object representation of a special JCR path element notably the root, the
- * current and the parent element.
- */
- private static final class SpecialElement extends Element {
-
- private final static int ROOT = 1;
- private final static int CURRENT = 2;
- private final static int PARENT = 4;
-
- private final int type;
-
- private SpecialElement(Name name) {
- super(name, Path.INDEX_UNDEFINED);
- if (ROOT_NAME.equals(name)) {
- type = ROOT;
- } else if (CURRENT_NAME.equals(name)) {
- type = CURRENT;
- } else if (PARENT_NAME.equals(name)) {
- type = PARENT;
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * @return true if this is the {@link #ROOT root element}.
- * @see Path.Element#denotesRoot()
- */
- @Override
- public boolean denotesRoot() {
- return type == ROOT;
- }
-
- /**
- * @return true if this is the {@link #PARENT parent element}.
- * @see Path.Element#denotesParent()
- */
- @Override
- public boolean denotesParent() {
- return type == PARENT;
- }
-
- /**
- * @return true if this is the {@link #CURRENT current element}.
- * @see Path.Element#denotesCurrent()
- */
- @Override
- public boolean denotesCurrent() {
- return type == CURRENT;
- }
-
- /**
- * @return Always returns false.
- * @see Path.Element#denotesName()
- */
- @Override
- public boolean denotesName() {
- return false;
- }
- }
-
- /**
- *
- */
- private static final class IdentifierElement extends Element {
-
- private final String identifier;
- /**
- *
- * @param identifier
- */
- private IdentifierElement(String identifier) {
- super(null, Path.INDEX_UNDEFINED);
- this.identifier = identifier;
- }
-
- /**
- * @return Always returns true.
- * @see Path.Element#denotesIdentifier()
- */
- @Override
- public boolean denotesIdentifier() {
- return true;
- }
-
- /**
- * @return Always returns false.
- * @see Path.Element#denotesName()
- */
- @Override
- public boolean denotesName() {
- return false;
- }
-
- /**
- * Returns a string representation of this path element. Note that
- * the path element name is expressed using the <code>{uri}name</code>
- * syntax.
- *
- * @return string representation of the path element
- * @see Object#toString()
- */
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append('[');
- sb.append(identifier);
- sb.append(']');
- return sb.toString();
- }
-
- /**
- * Computes a hash code for this path element.
- *
- * @return hash code
- * @see Object#hashCode()
- */
- @Override
- public int hashCode() {
- int h = 37 * 17 + identifier.hashCode();
- return h;
- }
-
- /**
- * Check for path element equality. Returns true if the given
- * object is a PathElement and contains the same name and index
- * as this one.
- *
- * @param obj the object to compare with
- * @return <code>true</code> if the path elements are equal
- * @see Object#equals(Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj instanceof IdentifierElement) {
- return identifier.equals(((IdentifierElement) obj).identifier);
- } if (obj instanceof Path.Element) {
- Path.Element other = (Path.Element) obj;
- return other.denotesIdentifier() && getString().equals(other.getString());
- }
- return false;
- }
- }
/**
* Builder internal class
*/
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/ElementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/ElementTest.java?rev=995483&r1=995482&r2=995483&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/ElementTest.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/name/ElementTest.java Thu Sep 9 16:28:02 2010
@@ -59,7 +59,7 @@ public class ElementTest extends TestCas
public void testNameElement() {
Element element =
- new NameElement(createName("test"), Path.INDEX_UNDEFINED);
+ NameElement.create(createName("test"), Path.INDEX_UNDEFINED);
assertFalse(element.denotesCurrent());
assertFalse(element.denotesIdentifier());
assertTrue(element.denotesName());
@@ -72,7 +72,7 @@ public class ElementTest extends TestCas
}
public void testIndexedNameElement() {
- Element element = new NameElement(createName("test"), 123);
+ Element element = NameElement.create(createName("test"), 123);
assertFalse(element.denotesCurrent());
assertFalse(element.denotesIdentifier());
assertTrue(element.denotesName());