Author: areshetnyak
Date: 2010-07-23 05:26:38 -0400 (Fri, 23 Jul 2010)
New Revision: 2810
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPathExt.java
Log:
EXOJCR-750 : Patch to JCR path management improvement was applied.
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPathExt.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPathExt.java
(rev 0)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPathExt.java 2010-07-23
09:26:38 UTC (rev 2810)
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+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 javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:geaz@users.sourceforge.net">Gennady Azarenkov
</a>
+ * @version $Id$
+ */
+
+public class JCRPathExt extends JCRPath
+{
+
+ private static PathElement[] EMPTY_PATH = new PathElement[0];
+
+ private static final PathElement THIS_ELEMENT = new
PathElement(Constants.NS_DEFAULT_URI, THIS_RELPATH, Constants.NS_EMPTY_PREFIX, -1);
+
+ private static final PathElement MOVE_UP_ELEMENT = new
PathElement(Constants.NS_DEFAULT_URI, PARENT_RELPATH, Constants.NS_EMPTY_PREFIX, -1);
+
+ protected final PathElement[] names;
+
+ protected final int size;
+
+ protected String cachedToString;
+
+ protected String cachedToStringShowIndex;
+
+ protected QPath cachedInternalQPath;
+
+ public final static JCRPathExt ROOT = new JCRPathExt();
+
+ private JCRPathExt()
+ {
+ this(EMPTY_PATH);
+ }
+
+ JCRPathExt(NamespaceAccessor namespaces, QPathEntry[] path) throws
RepositoryException
+ {
+ PathElement[] names = new PathElement[path.length];
+ int size = 0;
+ for (QPathEntry entry : path)
+ {
+ String prefix = namespaces.getNamespacePrefixByURI(entry.getNamespace());
+ PathElement element = element(entry.getNamespace(), entry.getName(), prefix,
entry.getIndex());
+ size = addEntry(names, size, element);
+ }
+
+ //
+ this.names = names;
+ this.size = size;
+ }
+
+ JCRPathExt(JCRPathExt that, PathElement[] addedEntries, int addedSize)
+ {
+ PathElement[] names = new PathElement[that.size + addedSize];
+ int size = 0;
+ for (int i = 0;i < that.size;i++)
+ {
+ size = addEntry(names, size, that.names[i]);
+ }
+ for (int i = 0;i < addedSize;i++)
+ {
+ size = addEntry(names, size, addedEntries[i]);
+ }
+
+ //
+ this.names = names;
+ this.size = size;
+ }
+
+ JCRPathExt(PathElement[] names)
+ {
+ this(names, names.length);
+ }
+
+ JCRPathExt(PathElement[] names, int size)
+ {
+ if (size < 0)
+ {
+ throw new AssertionError("Size value is negative: " + size);
+ }
+ if (size > names.length)
+ {
+ throw new AssertionError("Size value is too large: " + size + "
instead of max: " + names.length);
+ }
+
+ //
+ this.names = names;
+ this.size = size;
+ }
+
+ public boolean isAbsolute()
+ {
+ if (size > 0)
+ {
+ PathElement first = names[0];
+ if (first.getName().equals(ROOT_NAME))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ JCRPath add(JCRPath path)
+ {
+ return new JCRPathExt(this, ((JCRPathExt)path).names, ((JCRPathExt)path).size);
+ }
+
+ @Override
+ JCRPath addEntries(PathElement... entries)
+ {
+ return new JCRPathExt(this, entries, entries.length);
+ }
+
+ JCRPathExt addEntry(String namespace, String name, String prefix, int index)
+ {
+ return addEntry(element(namespace, name, prefix, index));
+ }
+
+ public JCRPathExt makeAncestorPath(int relativeDegree)
+ {
+ return new JCRPathExt(names, size - relativeDegree);
+ }
+
+ JCRPathExt addEntry(PathElement entry)
+ {
+ return new JCRPathExt(this, new PathElement[]{entry}, 1);
+ }
+
+ private static PathElement element(String namespace, String name, String prefix, int
index)
+ {
+ if (name.equals(THIS_RELPATH))
+ {
+ return THIS_ELEMENT;
+ }
+ else if (name.equals(PARENT_RELPATH))
+ {
+ return MOVE_UP_ELEMENT;
+ }
+ else
+ {
+ return new PathElement(namespace, name, prefix, index);
+ }
+ }
+
+ private static int addEntry(PathElement[] entries, int size, PathElement entry)
+ {
+ if (entry == THIS_ELEMENT)
+ {
+ return size;
+ }
+ if (size > 0 && entry == MOVE_UP_ELEMENT && !(entries[size - 1]
== MOVE_UP_ELEMENT))
+ {
+ if (size <= 0)
+ {
+ log.warn("Wrong relative path. Can't move up in path
hierarhy.");
+ return 0;
+ }
+ return size - 1;
+ }
+
+ //
+ entries[size] = entry;
+
+ //
+ return size + 1;
+ }
+
+ public JCRPathExt makeParentPath()
+ {
+ return makeAncestorPath(1);
+ }
+
+ @Override
+ public int getLength()
+ {
+ return size;
+ }
+
+ @Override
+ public PathElement getEntry(int index)
+ {
+ if (index > size)
+ {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return names[index];
+ }
+
+ public PathElement[] getRelPath(int relativeDegree)
+ {
+ PathElement[] relPath = new PathElement[relativeDegree];
+ System.arraycopy(names, size - relativeDegree, relPath, 0, relativeDegree);
+ return relPath;
+ }
+
+ public QPath getInternalPath()
+ {
+ if (cachedInternalQPath == null)
+ {
+ QPathEntry[] entries = new QPathEntry[size];
+
+ for (int i = 0; i < size; i++)
+ entries[i] = new QPathEntry(names[i].getNamespace(), names[i].getName(),
names[i].getIndex());
+
+ cachedInternalQPath = new QPath(entries);
+ }
+
+ return cachedInternalQPath;
+ }
+
+ public String getAsString(boolean showIndex)
+ {
+ if (showIndex)
+ {
+ if (cachedToStringShowIndex != null)
+ {
+ return cachedToStringShowIndex;
+ }
+ }
+ else
+ {
+ if (cachedToString != null)
+ {
+ return cachedToString;
+ }
+ }
+
+ // [PN] 27.06.07
+ String path;
+ if (isAbsolute())
+ {
+ if (size == 1)
+ {
+ path = "/";
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < size; i++)
+ {
+ builder.append("/").append(names[i].getAsString(showIndex));
+ }
+ path = builder.toString();
+ }
+ }
+ else
+ {
+ // relative
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < size; i++)
+ {
+ if (i > 0)
+ {
+ builder.append("/");
+ }
+ else
+ {
+
+ }
+ builder.append(names[i].getAsString(showIndex));
+ }
+ path = builder.toString();
+ }
+
+
+ //
+ if (showIndex)
+ {
+ cachedToStringShowIndex = path;
+ }
+ else
+ {
+ cachedToString = path;
+ }
+
+ //
+ return path;
+ }
+
+ public int getDepth()
+ {
+ return size - 1;
+ }
+
+ public boolean isDescendantOf(JCRPath ancestorLocation, boolean childOnly)
+ {
+ return isDescendantOf((JCRPathExt)ancestorLocation, childOnly);
+ }
+
+ public boolean isDescendantOf(JCRPathExt ancestorLocation, boolean childOnly)
+ {
+ int depthDiff = getDepth() - ancestorLocation.getDepth();
+ if (depthDiff <= 0 || (childOnly && depthDiff != 1))
+ return false;
+
+ JCRPathExt.PathElement[] anotherNames = ancestorLocation.names;
+ for (int i = 0; i < ancestorLocation.size; i++)
+ {
+ boolean result = anotherNames[i].equals(names[i]);
+ if (!result)
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isAncestorOf(JCRPath descendantLocation, boolean childOnly)
+ {
+ return descendantLocation.isDescendantOf(this, childOnly);
+ }
+
+ public PathElement getName()
+ {
+ if (size > 0)
+ return names[size - 1];
+
+ return THIS_ELEMENT;
+ }
+
+ public int getIndex()
+ {
+ return names[size - 1].getIndex();
+ }
+
+ public boolean isIndexSetExplicitly()
+ {
+ return names[size - 1].isIndexSetExplicitly();
+ }
+
+ public boolean isSameNameSibling(JCRPath anotherPath)
+ {
+ return isSameNameSibling((JCRPathExt)anotherPath);
+ }
+
+ public boolean isSameNameSibling(JCRPathExt anotherPath)
+ {
+ JCRName[] anotherNames = anotherPath.names;
+ for (int i = 0; i < anotherPath.size - 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());
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj instanceof JCRPathExt)
+ {
+ JCRPathExt other = (JCRPathExt)obj;
+ return this.getInternalPath().equals(other.getInternalPath());
+ }
+ return false;
+ }
+
+ public PathElement[] getEntries()
+ {
+ return names.clone();
+ }
+
+}
Property changes on:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/JCRPathExt.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native