jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Julian Reschke <julian.resc...@gmx.de>
Subject Re: properties with XML-Values; patch
Date Tue, 19 Feb 2008 09:57:48 GMT
Hm,

the code contains some ugly parts, I have to say.

I'm not sure how exactly this is supposed to work, because JCR doesn't 
have an XML property type. Are you trying to map this to child nodes, or 
are you trying to persist this as a JCR string property?

BR, Julian



Angela Schreiber wrote:
> hi roland
> 
> are you sure, it's not simply a bug in the dav-library?
> 
> assuming your client sends a valid and well-formed
> PROPPATCH body, i'd say that it should simply work
> without you having to create patches. and if it doesn't
> there might something wrong in the library.
> 
> that's what i would prefer to know first.
> am i missing something?
> angela
> 
> Roland Porath wrote:
>> I started a discussion about properties with xml-values on users.
>> Seems I got a patch to do just that.
>> Just thought I'd send it to the dev list. Maybe somebody finds it
>> interesting, maybe somebody finds a flaw in the code or the basic
>> assumptions.
>>
>> Seems like there were two separate problems:
>> 1. when trying to set the property 
>> WebdavRequestImpl.parsePropPatchRequest
>> did not recognise a property value as being xml
>> To patch that without having to patch the jars I created my own 
>> servlet that
>> instatiates my new implementation of WebdavRequest. (ExariWebdavRequest)
>>
>> 2. on propget the html encoding in the serialisation did some damage 
>> to my
>> beloved xml. (especially < and > turned into something scary, you know 
>> the
>> problem)
>> The fix was to create my own WebdavProperty implementation
>> (ExariWebdavProperty)
>>
>> I apologise for the somewhat jingoistic terminology.
>>
>> There's one snag however. Like I said I tried to keep the patch self
>> contained but currently I need to patch DavResourceImp.setProperty to
>> instantiate my property type instead of the default one. Any ideas how 
>> that
>> could be done better?
>>
>> Can you find anything that might cause trouble in my code? All my 
>> tests seem
>> to work fine but I can see my old mate Confirmation Bias lurking 
>> somewhere
>> in the corner.
>>
>> Here comes the code.
>>
>> Feedback and questions are more than welcome
>>
>> Cheers
>>
>> Roland
>>
>> CUT HERE 
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>
>> /*
>>  * 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.webdav.property;
>>
>> import java.io.IOException;
>> import java.io.StringReader;
>> import java.util.List;
>>
>> import javax.xml.parsers.DocumentBuilderFactory;
>> import javax.xml.parsers.FactoryConfigurationError;
>> import javax.xml.parsers.ParserConfigurationException;
>>
>> 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 org.w3c.dom.Node;
>> import org.w3c.dom.NodeList;
>> import org.w3c.dom.Text;
>> import org.xml.sax.InputSource;
>> import org.xml.sax.SAXException;
>>
>> /**
>>  * <code>DefaultDavProperty</code>...
>>  */
>> public class ExariWebdavProperty extends AbstractDavProperty {
>>
>>     private static Logger log =
>> LoggerFactory.getLogger(ExariWebdavProperty.class);
>>         protected Node node = null;
>>
>>     /**
>>      * the value of the property
>>      */
>>     private final Object value;
>>
>>     protected boolean isXML;
>>
>>     /**
>>      * instantiate a Property from a Node
>>      * if this ctor is called we know that it is a property containing
>> xml
>>      * @param node
>>      */
>>     private ExariWebdavProperty(Node node)
>>     {
>>         this(DavPropertyName.createFromXml((Element)node),
>> node.getNodeValue(), false);
>>         this.node = node;         this.isXML = true;
>>     }
>>    /**
>>      * Creates a new WebDAV property with the given
>> <code>DavPropertyName</code>
>>      * and value. If the property is meant to be protected the 
>> 'isProtected'
>>      * flag must be set to true.
>>      *
>>      * @param name the name of the property
>>      * @param value the value of the property
>>      * @param isProtected A value of true, defines this property to be
>> protected.
>>      * It will not be returned in a {@link
>> org.apache.jackrabbit.webdav.DavConstants#PROPFIND_ALL_PROP DAV:allprop}
>>      * PROPFIND request and cannot be set/removed with a PROPPATCH 
>> request.
>>      */
>>     private ExariWebdavProperty(DavPropertyName name, Object value, 
>> boolean
>> isProtected)     {
>>         super(name, isProtected);
>>         this.value = value;
>>     }
>>
>>     /**
>>      * Creates a new non- protected WebDAV property with the given
>>      * <code>DavPropertyName</code> and value.
>>      *
>>      * @param name the name of the property
>>      * @param value the value of the property
>>      */
>>     public ExariWebdavProperty(DavPropertyName name, Object value)     {
>>         this(name, value, false);
>>         try
>>         {
>>             Document doc =
>> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
>>             node = DomUtil.createElement(doc, name.getName(), null);
>>             Node valueNode =     
>> DocumentBuilderFactory.newInstance().newDocumentBuilder().
>>                     parse(new InputSource(new
>> StringReader((String) value))).getFirstChild();
>>             node.appendChild(doc.importNode(valueNode, true));
>>             isXML = true;
>>         }         catch (SAXException e)
>>         {
>>             //this is quite ugly; we're using  the exception to
>> determine if the content is xml
>>             //the exeption produces consoleoutput
>>             isXML= false;
>>         }         catch (IOException e)
>>         {
>>             e.printStackTrace();
>>         }         catch (ParserConfigurationException e)
>>         {
>>             e.printStackTrace();
>>         }         catch (FactoryConfigurationError e)
>>         {
>>
>>             e.printStackTrace();
>>         }
>>         if (log.isDebugEnabled()) log.debug("created: name=" +
>> name.getName() + ", value=" + value + ", isXML=" + isXML);
>>     }
>>
>>     /**
>>      * from AbstractDavProperty
>>      * @return the value of this property
>>      */
>>     public Object getValue()     {
>>         return value;
>>     }
>>
>>     /**
>>      * Create a new <code>DefaultDavProperty</code> instance from the

>> given
>> Xml
>>      * element. Name and namespace of the element are building the {@link
>> DavPropertyName},
>>      * while the element's content forms the property value. The 
>> following
>> logic
>>      * is applied:
>>      * <pre>
>>      * - empty Element           -&gt; <code>null</code> value
>>      * - single Text content     -&gt; <code>String</code> value
>>      * - single non-Text content -&gt; Element.getContent(0) is used as
>> value
>>      * - other: List obtained from Element.getContent() is used as value
>>      * </pre>
>>      *
>>      * @param propertyElement
>>      * @return
>>      */
>>     public static ExariWebdavProperty createFromXml(Element 
>> propertyElement)
>>
>>     {
>>         if (propertyElement == null)         {
>>             throw new IllegalArgumentException("Cannot create a new
>> DavProperty from a 'null' element.");
>>         }
>>         DavPropertyName name =
>> DavPropertyName.createFromXml(propertyElement);
>>         Object value;
>>         if (!DomUtil.hasContent(propertyElement)) {
>>             value = null;
>>         }  else {
>>             List c = DomUtil.getContent(propertyElement);
>>             value = getXmlPropertyValue((Node)c.get(0));
>>         }
>>         return new ExariWebdavProperty(name, value, false);
>>     }
>>         private static Object getXmlPropertyValue(Node node)
>>     {
>>         if (node.getNodeName().equals("#text"))
>>         {
>>             return node.getNodeValue();
>>         }
>>         else
>>         {
>>             return new ExariWebdavProperty(node);
>>         }
>>     }
>>     
>>     public Element toXml(Document document)
>>     {
>>         if (isXML)
>>         {
>>             return (Element) document.importNode(node, true);
>>         }
>>         else
>>         {
>>             Element property =
>> document.createElement(getName().getName());
>>             Text propValue =
>> document.createTextNode((String)value);
>>             property.appendChild(propValue);
>>             return property;
>>         }
>>     }
>>     
>>     public String toString()
>>     {
>>         return toXMLString(node);
>>     }
>>     
>>     private String toXMLString(Node node)
>>     {
>>         String result =  "";
>>         NodeList kids = node.getChildNodes();
>>         if (node.getNodeName().equals("#text"))
>>         {
>>             result = result + node.getNodeValue();
>>         }
>>         else
>>         {
>>             result = result + "<" + node.getNodeName() + ">";
>>             for (int kidCount=0; kidCount<kids.getLength();
>> kidCount++)
>>             {
>>                 result = result +
>> toXMLString(kids.item(kidCount));
>>             }
>>             result = result + "</" + node.getNodeName() + ">";
>>         }
>>         return result;
>>     }
>> }
>>
>>
>>
>>
>>
>>
> 


Mime
View raw message