Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/BinaryPartSource.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/BinaryPartSource.java (revision 0)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/BinaryPartSource.java (revision 0)
@@ -0,0 +1,58 @@
+/*
+ * 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.spi2dav;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.httpclient.methods.multipart.PartSource;
+import org.apache.jackrabbit.spi.QValue;
+
+import javax.jcr.RepositoryException;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * BinaryPartSource...
+ */
+public class BinaryPartSource implements PartSource {
+
+ private final QValue value;
+
+ BinaryPartSource(QValue value) {
+ this.value = value;
+ }
+
+ public long getLength() {
+ try {
+ return value.getLength();
+ } catch (RepositoryException e) {
+ throw new IllegalStateException(e.getMessage());
+ }
+ }
+
+ public String getFileName() {
+ return value.toString();
+ }
+
+ public InputStream createInputStream() throws IOException {
+ try {
+ return value.getStream();
+ } catch (RepositoryException e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+}
\ No newline at end of file
Property changes on: spi2dav\src\main\java\org\apache\jackrabbit\spi2dav\BinaryPartSource.java
___________________________________________________________________
Name: svn:keywords
+ author date id revision url
Name: svn:eol-style
+ native
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java (revision 617499)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ItemInfoImpl.java (working copy)
@@ -47,7 +47,11 @@
DavProperty pathProp = propSet.get(ItemResourceConstants.JCR_PATH);
String jcrPath = pathProp.getValue().toString();
path = resolver.getQPath(jcrPath);
+ }
+ public ItemInfoImpl(NodeId parentId, Path path) {
+ this.parentId = parentId;
+ this.path = path;
}
public NodeId getParentId() {
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/JcrStringPart.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/JcrStringPart.java (revision 0)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/JcrStringPart.java (revision 0)
@@ -0,0 +1,74 @@
+/*
+ * 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.spi2dav;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.httpclient.methods.multipart.PartBase;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.util.EncodingUtil;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * JcrStringPart...
+ */
+public class JcrStringPart extends PartBase {
+
+ private static Logger log = LoggerFactory.getLogger(JcrStringPart.class);
+
+ /** Default content type */
+ public static final String DEFAULT_CONTENT_TYPE = "text/plain";
+
+ /** Default charset */
+ public static final String DEFAULT_CHARSET = "UTF-8";
+
+ /** Default transfer encoding */
+ public static final String DEFAULT_TRANSFER_ENCODING = "8bit";
+
+ /** Content of this part */
+ private final byte[] content;
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the part
+ * @param contentType The content type, or null
+ */
+ public JcrStringPart(String name, String value, String contentType) {
+ super(name, contentType, DEFAULT_CHARSET, DEFAULT_TRANSFER_ENCODING);
+ if (contentType == null || value == null) {
+ throw new IllegalArgumentException("Value may not be null");
+ }
+ content = EncodingUtil.getBytes(value, DEFAULT_CHARSET);
+ }
+
+ /**
+ * @see Part#sendData(OutputStream)
+ */
+ protected void sendData(OutputStream out) throws IOException {
+ out.write(content);
+ }
+
+ /**
+ * @see Part#lengthOfData()
+ */
+ protected long lengthOfData() throws IOException {
+ return content.length;
+ }
+}
\ No newline at end of file
Property changes on: spi2dav\src\main\java\org\apache\jackrabbit\spi2dav\JcrStringPart.java
___________________________________________________________________
Name: svn:keywords
+ author date id revision url
Name: svn:eol-style
+ native
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java (revision 617499)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/PropertyInfoImpl.java (working copy)
@@ -16,26 +16,21 @@
*/
package org.apache.jackrabbit.spi2dav;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
-import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.PropertyId;
import org.apache.jackrabbit.spi.PropertyInfo;
import org.apache.jackrabbit.spi.QValue;
-import org.apache.jackrabbit.spi.QValueFactory;
-import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
-import org.apache.jackrabbit.webdav.jcr.property.ValuesProperty;
import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
import java.io.IOException;
/**
@@ -46,55 +41,47 @@
private static Logger log = LoggerFactory.getLogger(PropertyInfoImpl.class);
private final PropertyId id;
+ private final int type;
+ private final boolean isMultiValued;
- private int type;
- private boolean isMultiValued;
+ private ValueLoader loader;
private QValue[] values;
- public PropertyInfoImpl(PropertyId id, NodeId parentId, DavPropertySet propSet,
- NamePathResolver resolver, ValueFactory valueFactory,
- QValueFactory qValueFactory)
+ public PropertyInfoImpl(PropertyId id, DavPropertySet propSet,
+ NamePathResolver resolver, ValueLoader loader)
throws RepositoryException, DavException, IOException, NameException {
- super(parentId, propSet, resolver);
+ super(id.getParentId(), propSet, resolver);
+
+ if (loader == null) {
+ throw new IllegalArgumentException();
+ }
// set id
this.id = id;
+ this.loader = loader;
// retrieve properties
String typeName = propSet.get(ItemResourceConstants.JCR_TYPE).getValue().toString();
type = PropertyType.valueFromName(typeName);
-
- // values from jcr-server must be converted to qualified values.
- if (propSet.contains(ItemResourceConstants.JCR_VALUE)) {
- ValuesProperty vp = new ValuesProperty(propSet.get(ItemResourceConstants.JCR_VALUE), type, valueFactory);
- Value jcrValue = vp.getJcrValue(type, valueFactory);
- if (jcrValue == null) {
- // TODO: should never occur. since 'null' single values are not allowed. rather throw?
- values = QValue.EMPTY_ARRAY;
- } else {
- QValue qv;
- if (type == PropertyType.BINARY) {
- qv = qValueFactory.create(jcrValue.getStream());
- } else {
- qv = ValueFormat.getQValue(jcrValue, resolver, qValueFactory);
- }
- values = new QValue[] {qv};
- }
+ if (propSet.contains(ItemResourceConstants.JCR_LENGTH)) {
+ isMultiValued = false;
} else {
isMultiValued = true;
- ValuesProperty vp = new ValuesProperty(propSet.get(ItemResourceConstants.JCR_VALUES), type, valueFactory);
- Value[] jcrValues = vp.getJcrValues(type, valueFactory);
- values = new QValue[jcrValues.length];
- for (int i = 0; i < jcrValues.length; i++) {
- if (type == PropertyType.BINARY) {
- values[i] = qValueFactory.create(jcrValues[i].getStream());
- } else {
- values[i] = ValueFormat.getQValue(jcrValues[i], resolver, qValueFactory);
- }
- }
}
}
+ public PropertyInfoImpl(PropertyId id, Path path, int type,
+ boolean isMultiValued, QValue[] values) {
+ super(id.getParentId(), path);
+ if (values == null) {
+ throw new IllegalArgumentException();
+ }
+ this.id = id;
+ this.type = type;
+ this.isMultiValued = isMultiValued;
+ this.values = values;
+ }
+
//-----------------------------------------------------------< ItemInfo >---
public boolean denotesNode() {
return false;
@@ -118,6 +105,14 @@
}
public QValue[] getValues() {
+ if (values == null) {
+ try {
+ values = loader.loadValues(type, isMultiValued);
+ } catch (Exception e) {
+ log.error("Internal error while loading property value(s).", e);
+ throw new IllegalStateException("Unable to load property values.");
+ }
+ }
return values;
}
}
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QPropertyDefinitionImpl.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QPropertyDefinitionImpl.java (revision 617499)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QPropertyDefinitionImpl.java (working copy)
@@ -26,6 +26,8 @@
import org.apache.jackrabbit.webdav.xml.DomUtil;
import org.apache.jackrabbit.webdav.xml.ElementIterator;
import org.w3c.dom.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -40,6 +42,8 @@
*/
public class QPropertyDefinitionImpl extends QItemDefinitionImpl implements QPropertyDefinition {
+ private static Logger log = LoggerFactory.getLogger(QPropertyDefinitionImpl.class);
+
/**
* The required type.
*/
@@ -91,6 +95,10 @@
ElementIterator it = DomUtil.getChildren(child, DEFAULTVALUE_ELEMENT, null);
while (it.hasNext()) {
String jcrVal = DomUtil.getText(it.nextElement());
+ if (jcrVal == null) {
+ log.debug("PropertyDefinition: defaultValue is null -> ignoring");
+ continue;
+ }
QValue qValue;
if (requiredType == PropertyType.BINARY) {
// TODO: improve
@@ -101,7 +109,7 @@
}
vs.add(qValue);
}
- defaultValues = (QValue[]) vs.toArray(new QValue[vs.size()]);
+ defaultValues = (vs.isEmpty()) ? null : (QValue[]) vs.toArray(new QValue[vs.size()]);
}
child = DomUtil.getChildElement(pdefElement, VALUECONSTRAINTS_ELEMENT, null);
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (revision 617499)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (working copy)
@@ -26,7 +26,13 @@
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
import org.apache.jackrabbit.spi.commons.conversion.NameException;
@@ -173,6 +179,7 @@
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -832,7 +839,12 @@
// currently: missing 'value/values' property PropertyInfo cannot be built
// currently: missing prop-names with child-NodeInfo
List l = new ArrayList();
- l.add(getNodeInfo(sessionInfo, nodeId));
+ NodeInfo nInfo = getNodeInfo(sessionInfo, nodeId);
+ l.add(nInfo);
+ // at least add propertyInfos for the meta-props already known from the
+ // nodeInfo.
+ l.addAll(buildPropertyInfos(nInfo));
+
return l.iterator();
}
@@ -854,6 +866,41 @@
return nInfo;
}
+ private List buildPropertyInfos(NodeInfo nInfo) throws RepositoryException {
+ List l = new ArrayList(3);
+ NodeId nid = nInfo.getId();
+ Path nPath = nInfo.getPath();
+
+ if (nid.getPath() == null) {
+ PropertyId id = getIdFactory().createPropertyId(nid, NameConstants.JCR_UUID);
+ QValue[] vs = new QValue[] {getQValueFactory().create(nid.getUniqueID(), PropertyType.STRING)};
+ Path p = getPathFactory().create(nPath, NameConstants.JCR_UUID, true);
+ PropertyInfo pi = new PropertyInfoImpl(id, p, PropertyType.STRING, false, vs);
+ l.add(pi);
+ }
+
+ Name pName = NameConstants.JCR_PRIMARYTYPE;
+ QValue[] vs = new QValue[] {getQValueFactory().create(nInfo.getNodetype())};
+ PropertyInfo pi = new PropertyInfoImpl(getIdFactory().createPropertyId(nid, pName),
+ getPathFactory().create(nPath, pName, true), PropertyType.NAME, false, vs);
+ l.add(pi);
+
+ Name[] mixins = nInfo.getMixins();
+ if (mixins.length > 0) {
+ pName = NameConstants.JCR_MIXINTYPES;
+ vs = new QValue[mixins.length];
+ for (int i = 0; i < mixins.length; i++) {
+ vs[i] = getQValueFactory().create(mixins[i]);
+ }
+ pi = new PropertyInfoImpl(getIdFactory().createPropertyId(nid, pName),
+ getPathFactory().create(nPath, pName, true), PropertyType.NAME,
+ true, vs);
+ l.add(pi);
+ }
+
+ return l;
+ }
+
/**
* @see RepositoryService#getChildInfos(SessionInfo, NodeId)
*/
@@ -923,8 +970,8 @@
nameSet.add(ItemResourceConstants.JCR_NAME);
nameSet.add(ItemResourceConstants.JCR_PARENT);
nameSet.add(ItemResourceConstants.JCR_TYPE);
- nameSet.add(ItemResourceConstants.JCR_VALUE);
- nameSet.add(ItemResourceConstants.JCR_VALUES);
+ nameSet.add(ItemResourceConstants.JCR_LENGTH);
+ nameSet.add(ItemResourceConstants.JCR_LENGTHS);
nameSet.add(ItemResourceConstants.JCR_PATH);
nameSet.add(DavPropertyName.RESOURCETYPE);
@@ -932,7 +979,8 @@
try {
String uri = getItemUri(propertyId, sessionInfo);
method = new PropFindMethod(uri, nameSet, DEPTH_0);
- getClient(sessionInfo).executeMethod(method);
+ HttpClient client = getClient(sessionInfo);
+ client.executeMethod(method);
method.checkSuccess();
MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
@@ -945,8 +993,8 @@
PropertyId id = uriResolver.buildPropertyId(parentId, responses[0], sessionInfo.getWorkspaceName(), getNamePathResolver(sessionInfo));
NamePathResolver resolver = getNamePathResolver(sessionInfo);
- PropertyInfo pInfo = new PropertyInfoImpl(id, parentId, propSet,
- resolver, valueFactory, getQValueFactory());
+ PropertyInfo pInfo = new PropertyInfoImpl(id, propSet, resolver,
+ new ValueLoader(uri, client, getQValueFactory(), resolver));
return pInfo;
} catch (IOException e) {
throw new RepositoryException(e);
@@ -1896,7 +1944,7 @@
private BatchImpl(ItemId targetId, SessionInfo sessionInfo) throws RepositoryException {
this.targetId = targetId;
this.sessionInfo = sessionInfo;
- this.resolver = getNamePathResolver(sessionInfo);
+ resolver = getNamePathResolver(sessionInfo);
}
private HttpClient start() throws RepositoryException {
@@ -2023,9 +2071,12 @@
*/
public void addProperty(NodeId parentId, Name propertyName, QValue value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
checkConsumed();
- Value jcrValue = ValueFormat.getJCRValue(value, resolver, valueFactory);
- ValuesProperty vp = new ValuesProperty(jcrValue);
- internalAddProperty(parentId, propertyName, vp);
+ String uri = getItemUri(parentId, propertyName, sessionInfo);
+
+ PutMethod method = new PutMethod(uri);
+ method.setRequestHeader(DavConstants.HEADER_CONTENT_TYPE, getContentType(value.getType()));
+ method.setRequestEntity(getEntity(value));
+ methods.add(method);
}
/**
@@ -2033,22 +2084,19 @@
*/
public void addProperty(NodeId parentId, Name propertyName, QValue[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
checkConsumed();
- Value[] jcrValues = new Value[values.length];
- for (int i = 0; i < values.length; i++) {
- jcrValues[i] = ValueFormat.getJCRValue(values[i], resolver, valueFactory);
- }
- ValuesProperty vp = new ValuesProperty(jcrValues);
- internalAddProperty(parentId, propertyName, vp);
- }
-
- private void internalAddProperty(NodeId parentId, Name propertyName, ValuesProperty vp) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+ // TODO: avoid usage of the ValuesProperty. specially for binary props.
+ // TODO: replace by a multipart-POST
try {
String uri = getItemUri(parentId, propertyName, sessionInfo);
+ Value[] jcrValues = new Value[values.length];
+ for (int i = 0; i < values.length; i++) {
+ jcrValues[i] = ValueFormat.getJCRValue(values[i], resolver, valueFactory);
+ }
+ ValuesProperty vp = new ValuesProperty(jcrValues);
PutMethod method = new PutMethod(uri);
method.setRequestBody(vp);
methods.add(method);
-
} catch (IOException e) {
throw new RepositoryException(e);
}
@@ -2059,17 +2107,19 @@
*/
public void setValue(PropertyId propertyId, QValue value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
checkConsumed();
- DavPropertySet setProperties = new DavPropertySet();
if (value == null) {
// setting property value to 'null' is identical to a removal
remove(propertyId);
} else {
- // qualified value must be converted to jcr value
- Value jcrValue = ValueFormat.getJCRValue(value, resolver, valueFactory);
- ValuesProperty vp = new ValuesProperty(jcrValue);
- setProperties.add(vp);
+ RequestEntity ent = getEntity(value);
+ String uri = getItemUri(propertyId, sessionInfo);
+ // TODO: use PUT in order to avoid the ValuesProperty-PROPPATCH call.
+ // TODO: actually not quite correct for PROPPATCH assert that prop really exists.
+ PutMethod method = new PutMethod(uri);
+ method.setRequestHeader(DavConstants.HEADER_CONTENT_TYPE, getContentType(value.getType()));
+ method.setRequestEntity(ent);
+ methods.add(method);
}
- internalSetValue(propertyId, setProperties);
}
/**
@@ -2077,44 +2127,98 @@
*/
public void setValue(PropertyId propertyId, QValue[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
checkConsumed();
- DavPropertySet setProperties = new DavPropertySet();
if (values == null) {
// setting property value to 'null' is identical to a removal
remove(propertyId);
} else {
+ // TODO: use multipart-POST instead of ValuesProperty
+ DavPropertySet setProperties = new DavPropertySet();
// qualified values must be converted to jcr values
Value[] jcrValues = new Value[values.length];
for (int i = 0; i < values.length; i++) {
jcrValues[i] = ValueFormat.getJCRValue(values[i], resolver, valueFactory);
}
setProperties.add(new ValuesProperty(jcrValues));
+ try {
+ String uri = getItemUri(propertyId, sessionInfo);
+ PropPatchMethod method = new PropPatchMethod(uri, setProperties, new DavPropertyNameSet());
+ methods.add(method);
+ } catch (IOException e) {
+ throw new RepositoryException(e);
+ }
}
- internalSetValue(propertyId, setProperties);
}
+ private RequestEntity getEntity(QValue value) throws RepositoryException {
+ // qualified value must be converted to jcr value
+ InputStream in;
+ int type = value.getType();
+ String contentType = getContentType(type);
+ RequestEntity ent;
+ try {
+ switch (type) {
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ Value v = ValueFormat.getJCRValue(value, resolver, valueFactory);
+ ent = new StringRequestEntity(v.getString(), contentType, "UTF-8");
+ break;
+ case PropertyType.BINARY:
+ in = value.getStream();
+ ent = new InputStreamRequestEntity(in, contentType);
+ break;
+ default:
+ String str = value.getString();
+ ent = new StringRequestEntity(str, contentType, "UTF-8");
+ break;
+ }
+ } catch (UnsupportedEncodingException e) {
+ // should never get here
+ throw new RepositoryException(e.getMessage());
+ }
+ return ent;
+ }
+
/**
+ * Create a multipart request entity that would be used by {@link #addProperty}
+ * and {@link #setValue} taking an array of QValue objects.
+ * Currently this method is not used, since the jcr-server is not able
+ * to deal with multipart-post requests. (TODO: TOBEFIXED)
*
- * @param propertyId
- * @param setProperties
- * @throws ValueFormatException
- * @throws VersionException
- * @throws LockException
- * @throws ConstraintViolationException
- * @throws AccessDeniedException
- * @throws UnsupportedRepositoryOperationException
+ * @param values
+ * @param params
+ * @return
* @throws RepositoryException
*/
- private void internalSetValue(PropertyId propertyId, DavPropertySet setProperties) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
- try {
- String uri = getItemUri(propertyId, sessionInfo);
- PropPatchMethod method = new PropPatchMethod(uri, setProperties, new DavPropertyNameSet());
-
- methods.add(method);
- } catch (IOException e) {
- throw new RepositoryException(e);
+ private RequestEntity getEntity(QValue[] values, HttpMethodParams params) throws RepositoryException {
+ // qualified value must be converted to jcr value
+ Part[] parts = new Part[values.length];
+ for (int i = 0; i < values.length; i++) {
+ int type = values[i].getType();
+ String partname = i + "_" + PropertyType.nameFromValue(type);
+ String contentType = getContentType(type);
+ switch (type) {
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ Value v = ValueFormat.getJCRValue(values[i], resolver, valueFactory);
+ parts[i] = new JcrStringPart(partname, v.getString(), contentType);
+ break;
+ case PropertyType.BINARY:
+ parts[i] = new FilePart(partname, new BinaryPartSource(values[i]));
+ break;
+ default:
+ String str = values[i].getString();
+ parts[i] = new JcrStringPart(partname, str, contentType);
+ break;
+ }
}
+ RequestEntity ent = new MultipartRequestEntity(parts, params);
+ return ent;
}
+ private String getContentType(int type) {
+ return ItemResourceConstants.VALUE_CONTENT_TYPE_FRAGMENT + PropertyType.nameFromValue(type).toLowerCase();
+ }
+
/**
* @see Batch#remove(ItemId)
*/
Index: spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ValueLoader.java
===================================================================
--- spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ValueLoader.java (revision 0)
+++ spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/ValueLoader.java (revision 0)
@@ -0,0 +1,157 @@
+/*
+ * 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.spi2dav;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.QValueFactory;
+import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.commons.value.QValueValue;
+import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
+import org.apache.jackrabbit.webdav.jcr.property.ValuesProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.xml.parsers.DocumentBuilder;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * ValueLoader...
+ */
+class ValueLoader {
+
+ private static Logger log = LoggerFactory.getLogger(ValueLoader.class);
+
+ private final String uri;
+ private final HttpClient client;
+ private final QValueFactory factory;
+ private final ValueFactoryQImpl vf;
+ private final NamePathResolver resolver;
+
+ ValueLoader(String uri, HttpClient client, QValueFactory factory, NamePathResolver resolver) {
+ this.uri = uri;
+ this.client = client;
+ this.factory = factory;
+ this.resolver = resolver;
+
+ vf = new ValueFactoryQImpl(factory, resolver);
+ }
+
+ QValue[] loadValues(int type, boolean isMultiValued) throws IOException, RepositoryException {
+ if (type == PropertyType.BINARY) {
+ return loadBinary(uri, isMultiValued);
+ } else {
+ return loadString(uri, type, isMultiValued);
+ }
+ }
+
+ private QValue[] loadBinary(String uri, boolean isMultiValued) throws RepositoryException, IOException {
+ GetMethod method = new GetMethod(uri);
+ try {
+ int statusCode = client.executeMethod(method);
+ if (statusCode == DavServletResponse.SC_OK) {
+ if (isMultiValued) {
+ return getValues(method.getResponseBodyAsStream(), PropertyType.BINARY);
+ } else {
+ QValue v = factory.create(method.getResponseBodyAsStream());
+ return new QValue[] {v};
+ }
+ } else {
+ throw new RepositoryException("Unable to load binary. Status = " + statusCode);
+ }
+ } catch (HttpException e) {
+ throw new RepositoryException(e);
+ } finally {
+ method.releaseConnection();
+ }
+ }
+
+ private QValue[] loadString(String uri, int type, boolean isMultiValued) throws RepositoryException, IOException {
+ GetMethod method = new GetMethod(uri);
+ try {
+ int statusCode = client.executeMethod(method);
+ if (statusCode == DavServletResponse.SC_OK) {
+ if (isMultiValued) {
+ return getValues(method.getResponseBodyAsStream(), type);
+ } else {
+ String str = method.getResponseBodyAsString();
+ QValue v;
+ // name/path values from jcr-server must be converted to
+ // qualified values.
+ if (type == PropertyType.NAME) {
+ Name n = resolver.getQName(str);
+ v = factory.create(n);
+ } else if (type == PropertyType.PATH) {
+ Path p = resolver.getQPath(str);
+ v = factory.create(p);
+ } else {
+ v = factory.create(str, type);
+ }
+ return new QValue[] {v};
+ }
+ } else {
+ throw new RepositoryException("Unable to load binary. Status = " + statusCode);
+ }
+ } catch (HttpException e) {
+ throw new RepositoryException(e);
+ } finally {
+ method.releaseConnection();
+ }
+ }
+
+ private QValue[] getValues(InputStream response, int type) throws RepositoryException {
+ try {
+ DocumentBuilder db = DomUtil.BUILDER_FACTORY.newDocumentBuilder();
+ Document doc = db.parse(response);
+ Element prop = DomUtil.getChildElement(doc, ItemResourceConstants.JCR_VALUES.getName(), ItemResourceConstants.JCR_VALUES.getNamespace());
+ DavProperty p = DefaultDavProperty.createFromXml(prop);
+ ValuesProperty vp = new ValuesProperty(p, type, vf);
+
+ Value[] jcrVs = vp.getJcrValues(type, vf);
+ QValue[] qvs = new QValue[jcrVs.length];
+
+ for (int i = 0; i < jcrVs.length; i++) {
+ if (jcrVs[i] instanceof QValueValue) {
+ qvs[i] = ((QValueValue) jcrVs[i]).getQValue();
+ } else if (type == PropertyType.BINARY) {
+ qvs[i] = factory.create(jcrVs[i].getStream());
+ } else {
+ qvs[i] = factory.create(jcrVs[i].getString(), type);
+ }
+ }
+ return qvs;
+ } catch (Exception e) {
+ log.error("Internal Error: ", e);
+ throw new RepositoryException(e);
+ }
+ }
+}
\ No newline at end of file
Property changes on: spi2dav\src\main\java\org\apache\jackrabbit\spi2dav\ValueLoader.java
___________________________________________________________________
Name: svn:keywords
+ author date id revision url
Name: svn:eol-style
+ native