/*
* Copyright 2001-2008 Hippo (www.hippo.nl)
*
* Licensed 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 nl.hippo.cocoon.forms.binding;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.forms.binding.AbstractCustomBinding;
import org.apache.cocoon.forms.binding.BindingException;
import org.apache.cocoon.forms.formmodel.Widget;
import org.apache.cocoon.xml.XMLUtils;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.ri.model.beans.NullPropertyPointer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Custom binding for form elements containing XML as a string.
* It is assumed that the XML in the string has one unique root node
* as top level element.
*
* @author <a href="mailto:j.joachimsthal@hippo.nl">Jasha Joachimsthal</a>
*/
public class ChildXmlAsStringBinding extends AbstractCustomBinding
{
/**
* Serializes the node as String on load.
*
* @throws BindingException
* @see org.apache.cocoon.forms.binding.AbstractCustomBinding#doLoad(org.apache.cocoon.forms.formmodel.Widget,
* org.apache.commons.jxpath.JXPathContext)
*/
protected void doLoad(Widget widget, JXPathContext context) throws BindingException
{
Pointer pointer = context.getPointer(this.getXpath());
Node contextNode = (Node) pointer.getNode();
try
{
Properties props = new Properties();
props.put(OutputKeys.OMIT_XML_DECLARATION,"yes");
String xmlAsString=new String("");
if(contextNode != null && contextNode.hasChildNodes()){
NodeList children = contextNode.getChildNodes();
for(int i=0;i<children.getLength();i++){
xmlAsString = xmlAsString + XMLUtils.serializeNode((Node)children.item(i),props);
}
}
widget.setValue(xmlAsString);
}
catch (ProcessingException e)
{
throw new BindingException("Unable to serialize node", e);
}
}
/**
* Parses and imports the XML String on save.
*
* @throws IOException
* @throws SAXException
* @see org.apache.cocoon.forms.binding.AbstractCustomBinding#doSave(org.apache.cocoon.forms.formmodel.Widget,
* org.apache.commons.jxpath.JXPathContext)
*/
protected void doSave(Widget widget, JXPathContext context) throws BindingException,
SAXException, IOException
{
DocumentBuilder builder = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try
{
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e)
{
throw new BindingException("Problem getting a parser", e);
}
String content = (String) widget.getValue();
if(content!=null)
{
content = content.replaceAll("\r\n|\n","");
Document dom = builder.parse(new InputSource(new StringReader(content)));
Pointer pointer = context.getPointer(this.getXpath());
if(pointer instanceof NullPropertyPointer)
{
pointer = context.createPath(this.getXpath());
}
Node contextNode = (Node) pointer.getNode();
Node result = contextNode.getOwnerDocument().importNode(dom.getDocumentElement(), true);
// remove all of the context node's current children
while (contextNode.hasChildNodes())
{
contextNode.removeChild(contextNode.getFirstChild());
}
// append new children to context node
Node child = result;
while (child != null)
{
Node clonedChild = child.cloneNode(true);
contextNode.appendChild(clonedChild);
child = child.getNextSibling();
}
}
else{
Pointer pointer = context.getPointer(this.getXpath());
if(!(pointer instanceof NullPropertyPointer))
{
Node contextNode = (Node) pointer.getNode();
while (contextNode.hasChildNodes())
{
contextNode.removeChild(contextNode.getFirstChild());
}
}
}
content = "";
}
}
|