001    /**
002     *
003     * Copyright 2005 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.kernel.config.xstream;
018    
019    import javax.xml.parsers.DocumentBuilderFactory;
020    import javax.xml.parsers.DocumentBuilder;
021    import javax.xml.parsers.ParserConfigurationException;
022    
023    import com.thoughtworks.xstream.converters.Converter;
024    import com.thoughtworks.xstream.converters.MarshallingContext;
025    import com.thoughtworks.xstream.converters.UnmarshallingContext;
026    import com.thoughtworks.xstream.converters.ConversionException;
027    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
028    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
029    import com.thoughtworks.xstream.io.xml.DomReader;
030    import com.thoughtworks.xstream.io.xml.DomWriter;
031    import org.w3c.dom.Document;
032    import org.w3c.dom.Element;
033    import org.apache.geronimo.kernel.util.XmlUtil;
034    
035    /**
036     * @version $Rev: 428843 $ $Date: 2006-08-04 11:43:59 -0700 (Fri, 04 Aug 2006) $
037     */
038    public class DomConverter implements Converter {
039        public boolean canConvert(Class clazz) {
040            return Document.class.isAssignableFrom(clazz) || Element.class.isAssignableFrom(clazz);
041        }
042    
043        public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
044            DomReader reader;
045            if (object instanceof Document) {
046                Document doc = (Document) object;
047                reader = new DomReader(doc);
048            } else {
049                Element element = (Element) object;
050                reader = new DomReader(element);
051            }
052    
053            copy(reader, writer);
054        }
055    
056        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
057            DocumentBuilderFactory documentBuilderFactory = XmlUtil.newDocumentBuilderFactory();
058            DocumentBuilder documentBuilder = null;
059            try {
060                documentBuilder = documentBuilderFactory.newDocumentBuilder();
061            } catch (ParserConfigurationException e) {
062                throw new ConversionException("Cannot instantiate " + Document.class.getName(), e);
063            }
064            Document document = documentBuilder.newDocument();
065            DomWriter writer = new DomWriter(document);
066    
067            copy(reader, writer);
068    
069            if (Document.class.isAssignableFrom(unmarshallingContext.getRequiredType())) {
070                return document;
071            } else {
072                return document.getDocumentElement();
073            }
074        }
075    
076        public static void copy(HierarchicalStreamReader reader, HierarchicalStreamWriter writer) {
077            writer.startNode(reader.getNodeName());
078    
079            // write the attributes
080            int attributeCount = reader.getAttributeCount();
081            for (int i = 0; i < attributeCount; i++) {
082                String attributeName = reader.getAttributeName(i);
083                String attributeValue = reader.getAttribute(i);
084                writer.addAttribute(attributeName, attributeValue);
085            }
086    
087            // write the child nodes recursively
088            while (reader.hasMoreChildren()) {
089                reader.moveDown();
090                copy(reader, writer);
091                reader.moveUp();
092            }
093    
094            // write the context if any
095            String value = reader.getValue();
096            if (value != null && value.trim().length() > 0) {
097                writer.setValue(value);
098            }
099    
100            writer.endNode();
101        }
102    }