Index: jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (revision 1179240) +++ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (working copy) @@ -16,19 +16,6 @@ */ package org.apache.jackrabbit.spi2davex; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.jcr.Credentials; -import javax.jcr.ItemNotFoundException; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; - import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; @@ -62,13 +49,33 @@ import org.apache.jackrabbit.spi.commons.name.PathBuilder; import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl; import org.apache.jackrabbit.spi2dav.ExceptionConverter; +import org.apache.jackrabbit.spi2dav.ItemResourceConstants; import org.apache.jackrabbit.util.Text; +import org.apache.jackrabbit.webdav.DavConstants; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavServletResponse; +import org.apache.jackrabbit.webdav.MultiStatusResponse; +import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; import org.apache.jackrabbit.webdav.header.IfHeader; +import org.apache.jackrabbit.webdav.property.DavPropertyName; +import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; +import org.apache.jackrabbit.webdav.property.DavPropertySet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; +import javax.jcr.Credentials; +import javax.jcr.ItemNotFoundException; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + /** * RepositoryServiceImpl... */ @@ -90,6 +97,21 @@ private static final String DEFAULT_CHARSET = "UTF-8"; + private static final DavPropertyName JCR_TYPE = + DavPropertyName.create(ItemResourceConstants.JCR_TYPE_LN, ItemResourceConstants.NAMESPACE); + + private static final DavPropertyName JCR_LENGTH = + DavPropertyName.create(ItemResourceConstants.JCR_LENGTH_LN, ItemResourceConstants.NAMESPACE); + + private static final DavPropertyName JCR_LENGTHS = + DavPropertyName.create(ItemResourceConstants.JCR_LENGTHS_LN, ItemResourceConstants.NAMESPACE); + + private static final DavPropertyNameSet LAZY_PROPERTY_NAME_SET = new DavPropertyNameSet(){{ + add(JCR_TYPE); + add(JCR_LENGTH); + add(JCR_LENGTHS); + }}; + /** * base uri to the extended jcr-server that can handle the GET and POST * (or PATCH) requests sent by this service implementation. @@ -304,7 +326,7 @@ @Override public Iterator getItemInfos(SessionInfo sessionInfo, ItemId itemId) throws ItemNotFoundException, RepositoryException { if (!itemId.denotesNode()) { - PropertyInfo propertyInfo = super.getPropertyInfo(sessionInfo, (PropertyId) itemId); + PropertyInfo propertyInfo = getPropertyInfo(sessionInfo, (PropertyId) itemId); return Iterators.singleton(propertyInfo); } else { NodeId nodeId = (NodeId) itemId; @@ -348,6 +370,68 @@ } @Override + public PropertyInfo getPropertyInfo(SessionInfo sessionInfo, PropertyId propertyId) throws RepositoryException { + + final String uri = getItemUri(propertyId, sessionInfo); + PropFindMethod method = null; + try { + + method = new PropFindMethod(uri, LAZY_PROPERTY_NAME_SET, DavConstants.DEPTH_0); + getClient(sessionInfo).executeMethod(method); + method.checkSuccess(); + + final MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses(); + if (responses.length != 1) { + throw new ItemNotFoundException("Unable to retrieve the ItemInfo. No such node " + uri); + } + + final MultiStatusResponse response = responses[0]; + final DavPropertySet props = response.getProperties(DavServletResponse.SC_OK); + int propertyType = PropertyType.valueFromName((String) props.get(JCR_TYPE).getValue()); + + if (propertyType == PropertyType.BINARY) { + + boolean isMultiValued = props.get(JCR_LENGTHS) != null; + + if (isMultiValued) { + final List elements = (List) props.get(JCR_LENGTHS).getValue(); + final QValue[] qValues = new QValue[elements.size()]; + for (int i = 0 ; i < elements.size() ; i ++) { + final Element element = elements.get(i); + long length = Long.parseLong(element.getTextContent()); + qValues[i] = getQValueFactory(sessionInfo).create(length, uri, i); + } + return new PropertyInfoImpl( + propertyId, + propertyId.getPath(), + propertyType, + qValues); + } else { + long length = Long.parseLong((String)props.get(JCR_LENGTH).getValue()); + final QValue qValue = getQValueFactory(sessionInfo).create(length, uri, 0) ; + return new PropertyInfoImpl( + propertyId, + propertyId.getPath(), + propertyType, + qValue); + } + + } else { + return super.getPropertyInfo(sessionInfo, propertyId); + } + } catch (IOException e) { + log.error("Internal error while retrieving ItemInfo.",e); + throw new RepositoryException(e.getMessage()); + } catch (DavException e) { + throw ExceptionConverter.generate(e); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } + + @Override public Batch createBatch(SessionInfo sessionInfo, ItemId itemId) throws RepositoryException { return new BatchImpl(itemId, sessionInfo); }