Author: areshetnyak
Date: 2010-07-23 04:53:02 -0400 (Fri, 23 Jul 2010)
New Revision: 2809
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/InternalQName.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRName.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPath.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/LocationFactory.java
kernel/trunk/exo.kernel.commons/src/main/java/org/exoplatform/commons/utils/QName.java
Log:
EXOJCR-750 : Patch to JCR path management improvement was applied.
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/InternalQName.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/InternalQName.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/InternalQName.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -40,9 +40,14 @@
*/
public InternalQName(String namespace, String name)
{
- super(namespace, name);
+ super(safeIntern(namespace), safeIntern(name));
}
+ private static String safeIntern(String s)
+ {
+ return s != null ? s.intern() : null;
+ }
+
/**
* Parse qname in form of eXo-JCR names conversion string. E.g.
[name_space]item_name,
* [
http://www.jcp.org/jcr/nt/1.0]:base.
@@ -79,9 +84,18 @@
if (o == null)
return false;
- if (!(o instanceof InternalQName))
- return false;
+ if (o instanceof InternalQName)
+ {
+ InternalQName that = (InternalQName)o;
+ if (hashCode == that.hashCode)
+ {
+ String s1 = getAsString();
+ String s2 = that.getAsString();
+ return s1.equals(s2);
+ }
+ }
- return hashCode == o.hashCode() &&
getAsString().equals(((QName)o).getAsString());
+ return false;
+
}
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/datamodel/QPathEntry.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -32,6 +32,10 @@
*/
private final int index;
+ private String cachedToString;
+
+ private String cachedToStringShowIndex;
+
/**
* QPathEntry constructor.
*
@@ -128,7 +132,44 @@
*/
public String getAsString(boolean showIndex)
{
- return super.getAsString() + (showIndex ? QPath.PREFIX_DELIMITER + this.index :
"");
+ if (showIndex)
+ {
+ if (cachedToStringShowIndex != null)
+ {
+ return cachedToStringShowIndex;
+ }
+ }
+ else
+ {
+ if (cachedToString != null)
+ {
+ return cachedToString;
+ }
+ }
+
+ //
+ String res;
+ if (showIndex)
+ {
+ res = super.getAsString() + QPath.PREFIX_DELIMITER + this.index;
+ }
+ else
+ {
+ res = super.getAsString();
+ }
+
+ //
+ if (showIndex)
+ {
+ cachedToStringShowIndex = res;
+ }
+ else
+ {
+ cachedToString = res;
+ }
+
+ //
+ return res;
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRName.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRName.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRName.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -40,17 +40,43 @@
protected final int hashCode;
+ protected JCRName(InternalQName qname, String prefix)
+ {
+ this(qname.getNamespace(), qname.getName(), prefix);
+ }
+
+ JCRName(JCRPath.PathElement that)
+ {
+ this.prefix = that.prefix;
+ this.name = that.name;
+ this.namespace = that.namespace;
+ this.stringName = that.stringName;
+ this.hashCode = that.hashCode;
+ }
+
JCRName(String namespace, String name, String prefix)
{
- this.name = name.intern();
- this.namespace = namespace.intern();
- this.prefix = prefix.intern();
+ int hk = 31 + namespace.hashCode();
+ hk = hk * 31 + name.hashCode();
+ int hashCode = hk * 31 + prefix.hashCode();
- this.stringName = ((this.prefix.length() == 0 ? "" : this.prefix +
":") + this.name);
+ //
+ String stringName;
+ if (prefix.length() == 0)
+ {
+ stringName = name;
+ }
+ else
+ {
+ stringName = prefix + ":" + name;
+ }
- int hk = 31 + this.namespace.hashCode();
- hk = hk * 31 + this.name.hashCode();
- this.hashCode = hk * 31 + this.prefix.hashCode();
+ //
+ this.name = name;
+ this.namespace = namespace;
+ this.prefix = prefix;
+ this.stringName = stringName;
+ this.hashCode = hashCode;
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPath.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPath.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPath.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -18,16 +18,15 @@
*/
package org.exoplatform.services.jcr.impl.core;
+import org.exoplatform.services.jcr.core.NamespaceAccessor;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.jcr.datamodel.QPathEntry;
-import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import java.util.ArrayList;
+import javax.jcr.RepositoryException;
-import javax.jcr.PathNotFoundException;
-
/**
* Created by The eXo Platform SAS.
*
@@ -35,7 +34,7 @@
* @version $Id: JCRPath.java 11907 2008-03-13 15:36:21Z ksm $
*/
-public class JCRPath
+public abstract class JCRPath
{
public final static String ROOT_PATH = "/";
@@ -48,250 +47,117 @@
protected static Log log =
ExoLogger.getLogger("exo.jcr.component.core.JCRPath");
- protected PathElement[] names;
-
- JCRPath()
+ public static JCRPath createJCRPath()
{
- this.names = new PathElement[0];
+ return JCRPathExt.ROOT;
}
- public boolean isAbsolute()
+ public static JCRPath createJCRPath(NamespaceAccessor namespaces, QPath qpath) throws
RepositoryException
{
- if (names.length > 0)
- {
- PathElement first = names[0];
- if (first.getName().equals(ROOT_NAME))
- {
- return true;
- }
- }
- return false;
+ return new JCRPathExt(namespaces, qpath.getEntries());
}
- JCRPath addEntry(String namespace, String name, String prefix, int index)
+ public static JCRPath createJCRPath(NamespaceAccessor namespaces, QPathEntry[]
relPath) throws RepositoryException
{
- if (name.equals(THIS_RELPATH))
- return this;
-
- if (name.equals(PARENT_RELPATH))
- {
- return addEntry(new MoveUpElement());
- }
-
- return addEntry(new PathElement(namespace, name, prefix, index));
+ return new JCRPathExt(namespaces, relPath);
}
- JCRPath addEntry(PathElement entry)
- {
- if (names.length > 0 && entry instanceof MoveUpElement &&
!(names[names.length - 1] instanceof MoveUpElement))
- {
- return removeLastEntry();
- }
+ public abstract boolean isAbsolute();
- PathElement[] newNames = new PathElement[names.length + 1];
- for (int i = 0; i < names.length; i++)
- newNames[i] = names[i];
- newNames[names.length] = entry;
- names = newNames;
- return this;
- }
+ abstract JCRPath addEntry(String namespace, String name, String prefix, int index);
- JCRPath removeLastEntry()
- {
+ abstract JCRPath addEntry(PathElement entry);
- if (names.length <= 0)
- {
- log.warn("Wrong relative path. Can't move up in path hierarhy. " +
getAsString(true));
- return this;
- }
+ abstract JCRPath add(JCRPath path);
- PathElement[] newNames = new PathElement[names.length - 1];
- for (int i = 0; i < newNames.length; i++)
- newNames[i] = names[i];
- names = newNames;
- return this;
- }
+ abstract JCRPath addEntries(PathElement... entries);
- public JCRPath makeParentPath()
- {
- return makeAncestorPath(1);
- }
+ public abstract JCRPath makeParentPath();
- /**
- * Makes ancestor path by relative degree (For ex relativeDegree == 1 means parent
path etc)
- *
- * @param relativeDegree
- * @return
- * @throws PathNotFoundException
- */
- public JCRPath makeAncestorPath(int relativeDegree)
- {
+ public abstract JCRPath makeAncestorPath(int relativeDegree);
- JCRPath path = new JCRPath();
- for (int i = 0; i < names.length - relativeDegree; i++)
- path.addEntry(names[i]);
- return path;
- }
+ public abstract PathElement[] getRelPath(int relativeDegree);
- public PathElement[] getRelPath(int relativeDegree)
- {
- ArrayList<PathElement> entries = new ArrayList<PathElement>();
- for (int i = names.length - relativeDegree; i < names.length; i++)
- entries.add(names[i]);
- PathElement[] relPath = new PathElement[entries.size()];
- for (int i = 0; i < relPath.length; i++)
- relPath[i] = entries.get(i);
- return relPath;
- }
+ public abstract QPath getInternalPath();
- public QPath getInternalPath()
- {
+ public abstract String getAsString(boolean showIndex);
- QPathEntry[] entries = new QPathEntry[names.length];
+ public abstract int getDepth();
- for (int i = 0; i < names.length; i++)
- entries[i] = new QPathEntry(names[i].getNamespace(), names[i].getName(),
names[i].getIndex());
+ public abstract int getLength();
- QPath qpath = new QPath(entries);
- return qpath;
- }
+ public abstract PathElement getEntry(int index);
- public String getAsString(boolean showIndex)
- {
+ public abstract PathElement[] getEntries();
- // [PN] 27.06.07
- String path = "";
- if (isAbsolute())
- {
- if (size() == 1)
- return "/";
+ public abstract boolean isDescendantOf(JCRPath ancestorLocation, boolean childOnly);
- for (int i = 1; i < names.length; i++)
- {
- path += "/" + names[i].getAsString(showIndex);
- }
- }
- else
- {
- // relative
- for (int i = 0; i < names.length; i++)
- {
- path += i > 0 ? "/" + names[i].getAsString(showIndex) :
names[i].getAsString(showIndex);
- }
- }
+ public abstract boolean isAncestorOf(JCRPath descendantLocation, boolean childOnly);
- return path;
- }
+ public abstract PathElement getName();
- public int getDepth()
- {
- return size() - 1;
- }
+ public abstract int getIndex();
- public boolean isDescendantOf(JCRPath ancestorLocation, boolean childOnly)
- {
- int depthDiff = getDepth() - ancestorLocation.getDepth();
- if (depthDiff <= 0 || (childOnly && depthDiff != 1))
- return false;
+ public abstract boolean isIndexSetExplicitly();
- JCRPath.PathElement[] anotherNames = ancestorLocation.getEntries();
- for (int i = 0; i < anotherNames.length; i++)
- {
- boolean result = anotherNames[i].equals(names[i]);
- if (!result)
- return false;
- }
- return true;
- }
+ public abstract boolean isSameNameSibling(JCRPath anotherPath);
- public boolean isAncestorOf(JCRPath descendantLocation, boolean childOnly)
- {
- return descendantLocation.isDescendantOf(this, childOnly);
- }
+ public abstract boolean equals(Object obj);
- private int size()
+ protected JCRPath()
{
- return names.length;
}
- public JCRName getName()
+ public static class PathElement extends JCRName
{
- if (size() > 0)
- return names[size() - 1];
- return new ThisElement();
- }
+ private final int index;
- public int getIndex()
- {
- return names[size() - 1].getIndex();
- }
+ private final boolean indexSetExplicitly;
- public boolean isIndexSetExplicitly()
- {
- return names[size() - 1].isIndexSetExplicitly();
- }
+ private String cachedToString;
- public boolean isSameNameSibling(JCRPath anotherPath)
- {
- JCRName[] anotherNames = anotherPath.getEntries();
- for (int i = 0; i < anotherNames.length - 1; i++)
- {
- boolean result = anotherNames[i].equals(names[i]);
- if (!result)
- return false;
- }
- return getName().getName().equals(anotherPath.getName().getName())
- &&
this.getName().getPrefix().equals(anotherPath.getName().getPrefix());
- }
+ private String cachedToStringShowIndex;
- public boolean equals(Object obj)
- {
- if (this == obj)
+ public PathElement(String namespace, String name, String prefix, int index)
{
- return true;
- }
- if (obj instanceof JCRPath)
- {
- JCRPath other = (JCRPath)obj;
- return this.getInternalPath().equals(other.getInternalPath());
- }
- return false;
- }
+ super(namespace, name, prefix);
- PathElement[] getEntries()
- {
- return names;
- }
-
- public class ThisElement extends PathElement
- {
-
- ThisElement()
- {
- super(Constants.NS_DEFAULT_URI, THIS_RELPATH, Constants.NS_EMPTY_PREFIX, -1);
+ //
+ if (index == -1)
+ {
+ this.index = 1;
+ this.indexSetExplicitly = false;
+ }
+ else
+ {
+ this.index = index;
+ this.indexSetExplicitly = true;
+ }
}
- }
- public class MoveUpElement extends PathElement
- {
-
- MoveUpElement()
+ public PathElement(InternalQName qname, String prefix, int index)
{
- super(Constants.NS_DEFAULT_URI, PARENT_RELPATH, Constants.NS_EMPTY_PREFIX, -1);
+ super(qname, prefix);
+
+ //
+ if (index == -1)
+ {
+ this.index = 1;
+ this.indexSetExplicitly = false;
+ }
+ else
+ {
+ this.index = index;
+ this.indexSetExplicitly = true;
+ }
}
- }
- public class PathElement extends JCRName
- {
-
- private final int index;
-
- private final boolean indexSetExplicitly;
-
- public PathElement(String namespace, String name, String prefix, int index)
+ public PathElement(PathElement that, int index)
{
- super(namespace, name, prefix);
+ super(that);
+
+ //
if (index == -1)
{
this.index = 1;
@@ -306,7 +172,7 @@
public PathElement clone(int newIndex)
{
- return new PathElement(this.namespace, this.name, this.prefix, newIndex);
+ return new PathElement(this, newIndex);
}
public int getIndex()
@@ -324,12 +190,38 @@
public String getAsString(boolean showIndex)
{
- String indexStr;
+ if (showIndex)
+ {
+ if (cachedToStringShowIndex != null)
+ {
+ return cachedToStringShowIndex;
+ }
+ }
+ else
+ {
+ if (cachedToString != null)
+ {
+ return cachedToString;
+ }
+ }
+
+ StringBuffer sb = new StringBuffer(super.getAsString());
if (showIndex || getIndex() > 1)
- indexStr = "[" + getIndex() + "]";
+ sb.append("[").append(index).append("]");
+ String res = sb.toString();
+
+ //
+ if (showIndex)
+ {
+ cachedToStringShowIndex = res;
+ }
else
- indexStr = "";
- return (super.getAsString() + indexStr);
+ {
+ cachedToString = res;
+ }
+
+ //
+ return res;
}
public boolean isIndexSetExplicitly()
@@ -337,5 +229,4 @@
return indexSetExplicitly;
}
}
-
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/LocationFactory.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/LocationFactory.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/LocationFactory.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -65,19 +65,8 @@
*/
public JCRPath createJCRPath(JCRPath parentLoc, String relPath) throws
RepositoryException
{
-
- JCRPath path = new JCRPath();
- for (int i = 0; i < parentLoc.getEntries().length; i++)
- {
- path.addEntry(parentLoc.getEntries()[i]);
- }
-
JCRPath addPath = parseNames(relPath, false);
- for (int i = 0; i < addPath.getEntries().length; i++)
- {
- path.addEntry(addPath.getEntries()[i]);
- }
- return path;
+ return parentLoc.add(addPath);
}
/**
@@ -125,30 +114,21 @@
*/
public JCRPath createJCRPath(QPath qPath) throws RepositoryException
{
-
- JCRPath path = new JCRPath();
- for (int i = 0; i < qPath.getEntries().length; i++)
- {
- QPathEntry entry = qPath.getEntries()[i];
- String prefix = namespaces.getNamespacePrefixByURI(entry.getNamespace());
- path.addEntry(entry.getNamespace(), entry.getName(), prefix, entry.getIndex());
- }
-
- return path;
+ return JCRPath.createJCRPath(namespaces, qPath);
}
public JCRName createJCRName(InternalQName qname) throws RepositoryException
{
String prefix = namespaces.getNamespacePrefixByURI(qname.getNamespace());
- return new JCRName(qname.getNamespace(), qname.getName(), prefix);
+ return new JCRName(qname, prefix);
}
public String formatPathElement(QPathEntry qe) throws RepositoryException
{
String prefix = namespaces.getNamespacePrefixByURI(qe.getNamespace());
- JCRPath p = new JCRPath();
- p.addEntry(qe.getNamespace(), qe.getName(), prefix, qe.getIndex());
- return p.getEntries()[0].getAsString(false);
+ JCRPath p = JCRPath.createJCRPath();
+ p = p.addEntry(qe.getNamespace(), qe.getName(), prefix, qe.getIndex());
+ return p.getEntry(0).getAsString(false);
}
/**
@@ -160,25 +140,17 @@
*/
public JCRName parseJCRName(String name) throws RepositoryException
{
- JCRPath.PathElement entry = parsePathEntry(new JCRPath(), name);
-
- return new JCRName(entry.getNamespace(), entry.getName(), entry.getPrefix());
+ JCRPath path = parsePathEntry(JCRPath.createJCRPath(), name);
+ JCRPath.PathElement entry = path.getName();
+ return new JCRName(entry);
}
public JCRPath.PathElement[] createRelPath(QPathEntry[] relPath) throws
RepositoryException
{
- JCRPath path = new JCRPath();
- // JCRPath.PathElement[] entries = new JCRPath.PathElement[relPath.length];
- for (QPathEntry element : relPath)
- {
- String uri = namespaces.getNamespaceURIByPrefix(element.getNamespace());
- String prefix = namespaces.getNamespacePrefixByURI(uri);
- path.addEntry(uri, element.getName(), prefix, element.getIndex());
- }
- return path.getEntries();
+ return JCRPath.createJCRPath(namespaces, relPath).getEntries();
}
- private JCRPath.PathElement parsePathEntry(JCRPath path, String name) throws
RepositoryException
+ private JCRPath parsePathEntry(JCRPath path, String name) throws RepositoryException
{
// should be reset here (if there is explicit index) or
@@ -232,8 +204,8 @@
throw new RepositoryException("Illegal path entry: \"" + name
+ "\"");
}
- path.addEntry(namespaces.getNamespaceURIByPrefix(prefix), someName, prefix,
index);
- return (JCRPath.PathElement)path.getName();
+ path = path.addEntry(namespaces.getNamespaceURIByPrefix(prefix), someName,
prefix, index);
+ return path;
}
catch (Exception e)
@@ -250,7 +222,7 @@
throw new RepositoryException("Illegal relPath: \"" + path +
"\"");
}
- JCRPath jcrPath = new JCRPath();
+ JCRPath jcrPath = JCRPath.createJCRPath();
int start = 0;
if (!absolute)
{
@@ -262,7 +234,7 @@
{
throw new RepositoryException("Illegal relPath: \"" + path +
"\"");
}
- jcrPath.addEntry(namespaces.getNamespaceURIByPrefix(""), "",
"", -1);
+ jcrPath = jcrPath.addEntry(namespaces.getNamespaceURIByPrefix(""),
"", "", -1);
}
else
{
@@ -280,7 +252,7 @@
if (start + 1 != path.length())
{
- parsePathEntry(jcrPath, qname);
+ jcrPath = parsePathEntry(jcrPath, qname);
}
else
{
Modified:
kernel/trunk/exo.kernel.commons/src/main/java/org/exoplatform/commons/utils/QName.java
===================================================================
---
kernel/trunk/exo.kernel.commons/src/main/java/org/exoplatform/commons/utils/QName.java 2010-07-21
08:46:42 UTC (rev 2808)
+++
kernel/trunk/exo.kernel.commons/src/main/java/org/exoplatform/commons/utils/QName.java 2010-07-23
08:53:02 UTC (rev 2809)
@@ -37,14 +37,23 @@
protected final int hashCode;
public QName(String namespace, String name)
- {
- this.namespace = (namespace != null ? namespace : "").intern();
- this.name = (name != null ? name : "");
-
- this.stringName = ("[" + this.namespace + "]" + this.name);
-
- int hk = 31 + this.namespace.hashCode();
- this.hashCode = hk * 31 + this.name.hashCode();
+ {
+ if (namespace == null)
+ {
+ namespace = "";
+ }
+ if (name == null)
+ {
+ name = "";
+ }
+ String stringName = ("[" + namespace + "]" + name);
+ int hashCode = (31 + namespace.hashCode()) * 31 + name.hashCode();
+
+ //
+ this.namespace = namespace;
+ this.name = name;
+ this.stringName = stringName;
+ this.hashCode = hashCode;
}
public String getNamespace()