You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2010/05/17 16:00:02 UTC
svn commit: r945164 - in /jackrabbit/trunk:
jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/
jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/
Author: stefan
Date: Mon May 17 14:00:01 2010
New Revision: 945164
URL: http://svn.apache.org/viewvc?rev=945164&view=rev
Log:
JCR-2625: spi2davex: reduce memory footprint of Node/PropertyInfoImpl
Added:
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/StringCache.java
Modified:
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoJSONHandler.java
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PropertyInfoImpl.java
jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java
Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/StringCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/StringCache.java?rev=945164&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/StringCache.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/StringCache.java Mon May 17 14:00:01 2010
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.spi.commons.util;
+
+import java.lang.ref.SoftReference;
+
+/**
+ * A few String utility functions.
+ */
+public class StringCache {
+
+ public static final boolean OBJECT_CACHE = getBooleanSetting("jackrabbit.stringCache", true);
+ public static final int OBJECT_CACHE_SIZE = nextPowerOf2(getIntSetting("jackrabbit.stringCacheSize", 1024));
+
+ private static SoftReference<String[]> softCache = new SoftReference<String[]>(null);
+
+ private StringCache() {
+ // utility class
+ }
+
+ private static int nextPowerOf2(int x) {
+ long i = 1;
+ while (i < x && i < (Integer.MAX_VALUE / 2)) {
+ i += i;
+ }
+ return (int) i;
+ }
+
+ private static boolean getBooleanSetting(String name, boolean defaultValue) {
+ String s = getProperty(name);
+ if (s != null) {
+ try {
+ return Boolean.valueOf(s).booleanValue();
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return defaultValue;
+ }
+
+ private static int getIntSetting(String name, int defaultValue) {
+ String s = getProperty(name);
+ if (s != null) {
+ try {
+ return Integer.decode(s).intValue();
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return defaultValue;
+ }
+
+ private static String getProperty(String name) {
+ try {
+ return System.getProperty(name);
+ } catch (Exception e) {
+ // SecurityException
+ // applets may not do that - ignore
+ return null;
+ }
+ }
+
+ private static String[] getCache() {
+ String[] cache;
+ // softCache can be null due to a Tomcat problem
+ // a workaround is disable the system property org.apache.
+ // catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
+ if (softCache != null) {
+ cache = softCache.get();
+ if (cache != null) {
+ return cache;
+ }
+ }
+ try {
+ cache = new String[OBJECT_CACHE_SIZE];
+ } catch (OutOfMemoryError e) {
+ return null;
+ }
+ softCache = new SoftReference<String[]>(cache);
+ return cache;
+ }
+
+ /**
+ * Get the string from the cache if possible. If the string has not been
+ * found, it is added to the cache. If there is such a string in the cache,
+ * that one is returned.
+ *
+ * @param s the original string
+ * @return a string with the same content, if possible from the cache
+ */
+ public static String cache(String s) {
+ if (!OBJECT_CACHE) {
+ return s;
+ }
+ if (s == null) {
+ return s;
+ } else if (s.length() == 0) {
+ return "";
+ }
+ int hash = s.hashCode();
+ String[] cache = getCache();
+ if (cache != null) {
+ int index = hash & (OBJECT_CACHE_SIZE - 1);
+ String cached = cache[index];
+ if (cached != null) {
+ if (s.equals(cached)) {
+ return cached;
+ }
+ }
+ cache[index] = s;
+ }
+ return s;
+ }
+
+ /**
+ * Get a string from the cache, and if no such string has been found, create
+ * a new one with only this content. This solves out of memory problems if
+ * the string is a substring of another, large string. In Java, strings are
+ * shared, which could lead to memory problems. This avoid such problems.
+ *
+ * @param s the string
+ * @return a string that is guaranteed not be a substring of a large string
+ */
+ public static String fromCacheOrNew(String s) {
+ if (!OBJECT_CACHE) {
+ return s;
+ }
+ if (s == null) {
+ return s;
+ } else if (s.length() == 0) {
+ return "";
+ }
+ int hash = s.hashCode();
+ String[] cache = getCache();
+ int index = hash & (OBJECT_CACHE_SIZE - 1);
+ if (cache == null) {
+ return s;
+ }
+ String cached = cache[index];
+ if (cached != null) {
+ if (s.equals(cached)) {
+ return cached;
+ }
+ }
+ // create a new object that is not shared
+ // (to avoid out of memory if it is a substring of a big String)
+ // NOPMD
+ s = new String(s);
+ cache[index] = s;
+ return s;
+ }
+
+ /**
+ * Clear the cache. This method is used for testing.
+ */
+ public static void clearCache() {
+ softCache = new SoftReference<String[]>(null);
+ }
+
+}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoJSONHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoJSONHandler.java?rev=945164&r1=945163&r2=945164&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoJSONHandler.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoJSONHandler.java Mon May 17 14:00:01 2010
@@ -38,6 +38,8 @@ import org.apache.jackrabbit.spi.PathFac
import org.apache.jackrabbit.spi.PropertyId;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.util.StringCache;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,7 +51,7 @@ class ItemInfoJsonHandler implements Jso
private static Logger log = LoggerFactory.getLogger(ItemInfoJsonHandler.class);
- private static final int SPECIAL_JSON_PAIR = Integer.MAX_VALUE;
+ private static final String LEAF_NODE_HINT = "::NodeIteratorSize";
private final List<ItemInfo> itemInfos;
private final NamePathResolver resolver;
@@ -59,12 +61,19 @@ class ItemInfoJsonHandler implements Jso
private final PathFactory pFactory;
private final IdFactory idFactory;
+ private boolean expectingHintValue = false;
+
private Name name;
- private int propertyType;
private int index = Path.INDEX_DEFAULT;
+ // temp. property state
+ private int propertyType;
+ private boolean multiValuedProperty = false;
+ private List<QValue> propValues = new ArrayList<QValue>();
+
private Stack<NodeInfo> nodeInfos = new Stack<NodeInfo>();
- private PropertyInfoImpl mvPropInfo;
+
+ private Stack<List<PropertyInfoImpl>> propInfoLists = new Stack<List<PropertyInfoImpl>>();
ItemInfoJsonHandler(NamePathResolver resolver, NodeInfo nInfo,
String rootURI,
@@ -81,6 +90,7 @@ class ItemInfoJsonHandler implements Jso
itemInfos = new ArrayList<ItemInfo>();
itemInfos.add(nInfo);
nodeInfos.push(nInfo);
+ propInfoLists.push(new ArrayList<PropertyInfoImpl>(8));
}
public void object() throws IOException {
@@ -93,7 +103,7 @@ class ItemInfoJsonHandler implements Jso
Path p = pFactory.create(currentPath, relPath, true);
NodeInfo nInfo = new NodeInfoImpl(id, p);
nodeInfos.push(nInfo);
- itemInfos.add(nInfo);
+ propInfoLists.push(new ArrayList<PropertyInfoImpl>(8));
} catch (RepositoryException e) {
throw new IOException(e.getMessage());
}
@@ -103,7 +113,9 @@ class ItemInfoJsonHandler implements Jso
public void endObject() throws IOException {
try {
NodeInfoImpl nInfo = (NodeInfoImpl) nodeInfos.pop();
- nInfo.resolveUUID(idFactory);
+ List<PropertyInfoImpl> props = propInfoLists.pop();
+ // all required information to create a node info should now be gathered
+ nInfo.setPropertyInfos(props.toArray(new PropertyInfoImpl[props.size()]), idFactory);
NodeInfo parent = getCurrentNodeInfo();
if (parent != null) {
if (nInfo.getPath().getAncestor(1).equals(parent.getPath())) {
@@ -113,62 +125,80 @@ class ItemInfoJsonHandler implements Jso
log.debug("NodeInfo '"+ nInfo.getPath() + "' out of hierarchy. Parent path = " + parent.getPath());
}
}
- if (!nInfo.isCompleted()) {
+ if (nInfo.isCompleted()) {
+ itemInfos.addAll(props);
+ itemInfos.add(nInfo);
+ } else {
log.debug("Incomplete NodeInfo '"+ nInfo.getPath() + "' -> Only present as ChildInfo with its parent.");
- itemInfos.remove(nInfo);
}
} catch (RepositoryException e) {
throw new IOException(e.getMessage());
+ } finally {
+ // reset all node-related handler state
+ name = null;
+ index = Path.INDEX_DEFAULT;
}
}
public void array() throws IOException {
- try {
- mvPropInfo = createPropertyInfo(null, true);
- } catch (RepositoryException e) {
- throw new IOException(e.getMessage());
- }
+ multiValuedProperty = true;
+ propValues.clear();
}
public void endArray() throws IOException {
try {
- // make sure that type is set for mv-properties with empty value array.
- if (propertyType == PropertyType.UNDEFINED &&
- mvPropInfo.numberOfValues() == 0) {
- int type = vFactory.retrieveType(getValueURI());
- mvPropInfo.setType(type);
+ if (propertyType == PropertyType.UNDEFINED) {
+ if (propValues.isEmpty()) {
+ // make sure that type is set for mv-properties with empty value array.
+ propertyType = vFactory.retrieveType(getValueURI());
+ } else {
+ propertyType = propValues.get(0).getType();
+ }
}
- mvPropInfo.checkCompleted();
- getCurrentNodeInfo().addPropertyInfo(mvPropInfo, idFactory);
- mvPropInfo = null;
+ // create multi-valued property info
+ NodeInfoImpl parent = getCurrentNodeInfo();
+ Path p = pFactory.create(parent.getPath(), name, true);
+ PropertyId id = idFactory.createPropertyId(parent.getId(), name);
+ PropertyInfoImpl propInfo = new PropertyInfoImpl(id, p, propertyType, propValues.toArray(new QValue[propValues.size()]));
+ propInfo.checkCompleted();
+ getCurrentPropInfos().add(propInfo);
} catch (RepositoryException e) {
throw new IOException(e.getMessage());
+ } finally {
+ // reset property-related handler state
+ propertyType = PropertyType.UNDEFINED;
+ multiValuedProperty = false;
+ propValues.clear();
+ name = null;
}
}
public void key(String key) throws IOException {
+ expectingHintValue = false;
try {
- if (key.equals("::NodeIteratorSize")) {
- propertyType = SPECIAL_JSON_PAIR;
- // TODO: if additional JSON pairs are created -> set name
+ if (key.equals(LEAF_NODE_HINT)) {
+ expectingHintValue = true;
+ // TODO: remember name of hint if there will be additional types of hints
+ name = null;
} else if (key.startsWith(":")) {
- // binary property
- name = resolver.getQName(key.substring(1));
- propertyType = PropertyType.BINARY;
+ expectingHintValue = true;
+ // either
+ // :<nameOfProperty> : "PropertyTypeName"
+ // or
+ // :<nameOfBinaryProperty> : <lengthOfBinaryProperty>
+ //name = resolver.getQName(key.substring(1));
+ name = resolver.getQName(StringCache.fromCacheOrNew(key.substring(1)));
index = Path.INDEX_DEFAULT;
} else if (key.endsWith("]")) {
// sns-node name
int pos = key.lastIndexOf('[');
- name = resolver.getQName(key.substring(0, pos));
+ //name = resolver.getQName(key.substring(0, pos));
+ name = resolver.getQName(StringCache.fromCacheOrNew(key.substring(0, pos)));
propertyType = PropertyType.UNDEFINED;
index = Integer.parseInt(key.substring(pos + 1, key.length() - 1));
} else {
// either node or property
- Name previousName = name;
- name = resolver.getQName(key);
- propertyType = guessPropertyType(name, previousName);
- // property type is defined through json value OR special property
- // :propertyName = type.
+ name = resolver.getQName(StringCache.cache(key));
index = Path.INDEX_DEFAULT;
}
} catch (RepositoryException e) {
@@ -176,21 +206,27 @@ class ItemInfoJsonHandler implements Jso
}
}
+ /**
+ * there is currently one special string-value hint:
+ *
+ * :<nameOfProperty> : "PropertyTypeName"
+ *
+ * @param value The value.
+ * @throws IOException
+ */
public void value(String value) throws IOException {
+ if (expectingHintValue) {
+ // :<nameOfProperty> : "PropertyTypeName"
+ propertyType = PropertyType.valueFromName(value);
+ return;
+ }
try {
QValue v;
switch (propertyType) {
- case SPECIAL_JSON_PAIR:
- // currently no special boolean value pair -> ignore
- return;
- case PropertyType.BINARY:
- // key started with ':' but value is String instead of
- // long. value therefore reflects the property type.
- // -> reset the property type.
- // -> omit creation of value AND call to value(QValue)
- propertyType = PropertyType.valueFromName(value);
- return;
case PropertyType.UNDEFINED:
+ if (!NameConstants.JCR_UUID.equals(name)) {
+ value = StringCache.cache(value);
+ }
v = vFactory.create(value, PropertyType.STRING);
break;
case PropertyType.NAME:
@@ -209,8 +245,8 @@ class ItemInfoJsonHandler implements Jso
}
public void value(boolean value) throws IOException {
- if (propertyType == SPECIAL_JSON_PAIR) {
- // currently no special boolean value pair -> ignore
+ if (expectingHintValue) {
+ // there are currently no special boolean value hints:
return;
}
try {
@@ -220,30 +256,46 @@ class ItemInfoJsonHandler implements Jso
}
}
+ /**
+ * there are currently 2 types of special long value hints:
+ *
+ * a) ::NodeIteratorSize : 0
+ * ==> denotes the current node as leaf node
+ *
+ * b) :<nameOfBinaryProperty> : <lengthOfBinaryProperty>
+ *
+ * @param value The value.
+ * @throws IOException
+ */
public void value(long value) throws IOException {
- if (propertyType == SPECIAL_JSON_PAIR) {
- NodeInfoImpl parent = getCurrentNodeInfo();
- if (parent != null) {
- parent.setNumberOfChildNodes(value);
+ if (expectingHintValue) {
+ if (name == null) {
+ // ::NodeIteratorSize : 0
+ NodeInfoImpl parent = getCurrentNodeInfo();
+ if (parent != null) {
+ parent.markAsLeafNode();
+ }
+ } else {
+ // :<nameOfBinaryProperty> : <lengthOfBinaryProperty>
+ propertyType = PropertyType.BINARY;
+ try {
+ int indx = (!multiValuedProperty) ? -1 : propValues.size();
+ value(vFactory.create(value, getValueURI(), indx));
+ } catch (RepositoryException e) {
+ throw new IOException(e.getMessage());
+ }
}
return;
}
try {
- QValue v;
- if (propertyType == PropertyType.BINARY) {
- int indx = (mvPropInfo == null) ? -1 : mvPropInfo.numberOfValues();
- v = vFactory.create(value, getValueURI(), indx);
- } else {
- v = vFactory.create(value);
- }
- value(v);
+ value(vFactory.create(value));
} catch (RepositoryException e) {
throw new IOException(e.getMessage());
}
}
public void value(double value) throws IOException {
- if (propertyType == SPECIAL_JSON_PAIR) {
+ if (expectingHintValue) {
// currently no special double value pair -> ignore
return;
}
@@ -261,10 +313,31 @@ class ItemInfoJsonHandler implements Jso
* @throws RepositoryException
*/
private void value(QValue value) throws RepositoryException {
- if (mvPropInfo == null) {
- createPropertyInfo(value, false);
+ if (!multiValuedProperty) {
+ try {
+ if (propertyType == PropertyType.UNDEFINED) {
+ propertyType = value.getType();
+ }
+ // create single-valued property info
+ NodeInfoImpl parent = getCurrentNodeInfo();
+ Path p = pFactory.create(parent.getPath(), name, true);
+ PropertyId id = idFactory.createPropertyId(parent.getId(), name);
+ PropertyInfoImpl propInfo = new PropertyInfoImpl(id, p, propertyType, value);
+ propInfo.checkCompleted();
+ // add property info to current list, will be processed on endObject() event
+ getCurrentPropInfos().add(propInfo);
+ } finally {
+ // reset property-related handler state
+ propertyType = PropertyType.UNDEFINED;
+ multiValuedProperty = false;
+ propValues.clear();
+ name = null;
+ expectingHintValue = false;
+ }
} else {
- mvPropInfo.addValue(value);
+ // multi-valued property
+ // add value to current list, will be processed on endArray() event
+ propValues.add(value);
}
}
@@ -273,48 +346,17 @@ class ItemInfoJsonHandler implements Jso
}
private NodeInfoImpl getCurrentNodeInfo() {
- return (nodeInfos.isEmpty()) ? null : (NodeInfoImpl) nodeInfos.peek();
+ return (nodeInfos.isEmpty()) ? null : (NodeInfoImpl) nodeInfos.peek();
}
- private PropertyInfoImpl createPropertyInfo(QValue value, boolean isMultiValued) throws RepositoryException {
- NodeInfoImpl parent = getCurrentNodeInfo();
- Path p = pFactory.create(parent.getPath(), name, true);
- PropertyId id = idFactory.createPropertyId(parent.getId(), name);
-
- PropertyInfoImpl pInfo;
- if (isMultiValued) {
- pInfo = new PropertyInfoImpl(id, p, propertyType);
- // not added to parent but upon having read all values.
- } else {
- pInfo = new PropertyInfoImpl(id, p, propertyType, value);
- parent.addPropertyInfo(pInfo, idFactory);
- }
- itemInfos.add(pInfo);
- return pInfo;
+ private List<PropertyInfoImpl> getCurrentPropInfos() {
+ return (propInfoLists.isEmpty()) ? null : propInfoLists.peek();
}
private String getValueURI() throws RepositoryException {
- Path propertyPath;
- if (mvPropInfo == null) {
- propertyPath = pFactory.create(getCurrentNodeInfo().getPath(), name, true);
- } else {
- propertyPath = mvPropInfo.getPath();
- }
+ Path propertyPath = pFactory.create(getCurrentNodeInfo().getPath(), name, true);
StringBuffer sb = new StringBuffer(rootURI);
sb.append(Text.escapePath(resolver.getJCRPath(propertyPath)));
return sb.toString();
}
-
- private int guessPropertyType(Name name, Name previousName) {
- if (name.equals(previousName)) {
- // property has been previously retrieved from :name : "typeName"
- // entry in the JSON string. if by coincidence the previous key
- // is equal but belongs to an JSON object (-> node) the prop type
- // has been reset to UNDEFINED anyway.
- return propertyType;
- } else {
- // default: determine type upon Property.getType() only.
- return PropertyType.UNDEFINED;
- }
- }
}
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java?rev=945164&r1=945163&r2=945164&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java Mon May 17 14:00:01 2010
@@ -19,9 +19,7 @@ package org.apache.jackrabbit.spi2davex;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Set;
import javax.jcr.RepositoryException;
@@ -32,7 +30,6 @@ import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.NodeInfo;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.PropertyId;
-import org.apache.jackrabbit.spi.PropertyInfo;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.commons.name.NameConstants;
@@ -41,13 +38,13 @@ import org.apache.jackrabbit.spi.commons
*/
public class NodeInfoImpl extends ItemInfoImpl implements NodeInfo {
+ // data deduced from property values
private NodeId id;
- private String uniqueID;
private Name primaryNodeTypeName;
private Name[] mixinNodeTypeNames = Name.EMPTY_ARRAY;
- private final Set<PropertyInfo> propertyInfos = new LinkedHashSet<PropertyInfo>();
- private Set<ChildInfo> childInfos = null;
+ private final List<PropertyId> propertyIds = new ArrayList<PropertyId>(8);
+ private List<ChildInfo> childInfos = null;
/**
* Creates a new <code>NodeInfo</code>.
@@ -83,11 +80,7 @@ public class NodeInfoImpl extends ItemIn
}
public Iterator<PropertyId> getPropertyIds() {
- List<PropertyId> l = new ArrayList<PropertyId>();
- for (PropertyInfo propertyInfo : propertyInfos) {
- l.add(propertyInfo.getId());
- }
- return l.iterator();
+ return propertyIds.iterator();
}
public Iterator<ChildInfo> getChildInfos() {
@@ -95,58 +88,55 @@ public class NodeInfoImpl extends ItemIn
}
//--------------------------------------------------------------------------
- void addPropertyInfo(PropertyInfoImpl propInfo, IdFactory idFactory) throws RepositoryException {
- propertyInfos.add(propInfo);
-
- Name pn = propInfo.getId().getName();
- if (NameConstants.JCR_UUID.equals(pn)) {
- uniqueID = propInfo.getValues()[0].getString();
- id = idFactory.createNodeId(uniqueID);
- } else if (NameConstants.JCR_PRIMARYTYPE.equals(pn)) {
- primaryNodeTypeName = propInfo.getValues()[0].getName();
- } else if (NameConstants.JCR_MIXINTYPES.equals(pn)) {
- QValue[] vs = propInfo.getValues();
- Name[] mixins = new Name[vs.length];
- for (int i = 0; i < vs.length; i++) {
- mixins[i] = vs[i].getName();
+ void setPropertyInfos(PropertyInfoImpl[] propInfos, IdFactory idFactory) throws RepositoryException {
+ boolean resolveUUID = false;
+ for (PropertyInfoImpl propInfo : propInfos) {
+ Name pn = propInfo.getId().getName();
+ if (NameConstants.JCR_UUID.equals(pn)) {
+ id = idFactory.createNodeId(propInfo.getValues()[0].getString());
+ resolveUUID = true;
+ } else if (NameConstants.JCR_PRIMARYTYPE.equals(pn)) {
+ primaryNodeTypeName = propInfo.getValues()[0].getName();
+ } else if (NameConstants.JCR_MIXINTYPES.equals(pn)) {
+ QValue[] vs = propInfo.getValues();
+ Name[] mixins = new Name[vs.length];
+ for (int i = 0; i < vs.length; i++) {
+ mixins[i] = vs[i].getName();
+ }
+ mixinNodeTypeNames = mixins;
}
- mixinNodeTypeNames = mixins;
}
- }
- void resolveUUID(IdFactory idFactory) {
- if (uniqueID != null) {
- for (Object o : propertyInfos) {
- PropertyInfoImpl propInfo = (PropertyInfoImpl) o;
+ propertyIds.clear();
+ for (PropertyInfoImpl propInfo : propInfos) {
+ if (resolveUUID) {
propInfo.setId(idFactory.createPropertyId(id, propInfo.getName()));
}
+ propertyIds.add(propInfo.getId());
}
+
}
void addChildInfo(ChildInfo childInfo) {
if (childInfos == null) {
- childInfos = new LinkedHashSet<ChildInfo>();
+ childInfos = new ArrayList<ChildInfo>();
}
childInfos.add(childInfo);
}
- void setNumberOfChildNodes(long numberOfChildNodes) {
- if (numberOfChildNodes == 0) {
- childInfos = Collections.<ChildInfo>emptySet();
- } // else: wait for calls to #addChildInfo
+ void markAsLeafNode() {
+ childInfos = Collections.emptyList();
}
boolean isCompleted() {
- return !(id == null || primaryNodeTypeName == null || propertyInfos.isEmpty());
- }
-
- void checkCompleted() throws RepositoryException {
- if (!isCompleted()) {
- throw new RepositoryException("Incomplete NodeInfo");
- }
+ return (id != null && primaryNodeTypeName != null && !propertyIds.isEmpty());
}
String getUniqueID() {
- return uniqueID;
+ if (id.getUniqueID() != null && id.getPath() == null) {
+ return id.getUniqueID();
+ } else {
+ return null;
+ }
}
}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PropertyInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PropertyInfoImpl.java?rev=945164&r1=945163&r2=945164&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PropertyInfoImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PropertyInfoImpl.java Mon May 17 14:00:01 2010
@@ -23,34 +23,33 @@ import org.apache.jackrabbit.spi.QValue;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import java.util.ArrayList;
-import java.util.List;
/**
* <code>PropertyInfoImpl</code>...
*/
public class PropertyInfoImpl extends ItemInfoImpl implements PropertyInfo {
- private final boolean isMultiValued;
+ private final boolean multiValued;
private PropertyId id;
private int propertyType;
- private List<QValue> values = new ArrayList<QValue>();
+ private QValue[] values = QValue.EMPTY_ARRAY;
public PropertyInfoImpl(PropertyId id, Path path, int propertyType,
- QValue singleValue) throws RepositoryException {
+ QValue value) throws RepositoryException {
super(path, false);
this.id = id;
this.propertyType = propertyType;
- isMultiValued = false;
- values.add(singleValue);
+ multiValued = false;
+ values = new QValue[]{value};
}
- public PropertyInfoImpl(PropertyId id, Path path, int propertyType) throws RepositoryException {
+ public PropertyInfoImpl(PropertyId id, Path path, int propertyType, QValue[] values) throws RepositoryException {
super(path, false);
this.id = id;
this.propertyType = propertyType;
- isMultiValued = true;
+ this.values = values;
+ multiValued = true;
}
//-------------------------------------------------------< PropertyInfo >---
@@ -68,41 +67,24 @@ public class PropertyInfoImpl extends It
}
public boolean isMultiValued() {
- return isMultiValued;
+ return multiValued;
}
public QValue[] getValues() {
- return values.toArray(new QValue[values.size()]);
+ return values;
}
//--------------------------------------------------------------------------
- int numberOfValues() {
- return values.size();
- }
-
void setId(PropertyId id) {
this.id = id;
}
- void addValue(QValue value) throws RepositoryException {
- if (values == null) {
- values = new ArrayList<QValue>();
- } else if (!isMultiValued && !values.isEmpty()) {
- throw new RepositoryException("Attempt to add multiple values to a single valued PropertyInfo");
- }
- values.add(value);
- }
-
- void setType(int propertyType) {
- this.propertyType = propertyType;
- }
-
void checkCompleted() throws RepositoryException {
if (id == null) {
throw new RepositoryException("Incomplete PropertyInfo: id missing.");
}
- if (values.size() == 0 && propertyType == PropertyType.UNDEFINED) {
- throw new RepositoryException("Incomplete PropertyInfo: missing type of multivalued property.");
+ if (propertyType == PropertyType.UNDEFINED) {
+ throw new RepositoryException("Incomplete PropertyInfo: missing type of property.");
}
}
}
Modified: jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java?rev=945164&r1=945163&r2=945164&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ValueLoader.java Mon May 17 14:00:01 2010
@@ -94,7 +94,7 @@ class ValueLoader {
//--------------------------------------------------------------------------
/**
- * Internal inteface
+ * Internal interface
*/
interface Target {
/**