jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Angela Schreiber <anch...@day.com>
Subject Re: properties with XML-Values; patch
Date Tue, 19 Feb 2008 09:45:38 GMT
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