001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.ken.util;
017
018import java.io.StringReader;
019import java.io.StringWriter;
020import java.util.HashMap;
021import java.util.Iterator;
022
023import javax.xml.transform.ErrorListener;
024import javax.xml.transform.Source;
025import javax.xml.transform.Transformer;
026import javax.xml.transform.TransformerException;
027import javax.xml.transform.TransformerFactory;
028import javax.xml.transform.stream.StreamResult;
029import javax.xml.transform.stream.StreamSource;
030
031import org.apache.log4j.Logger;
032
033/**
034 * This class handles XSLT transformations.
035 * @author Kuali Rice Team (rice.collab@kuali.org)
036 */
037public class ContentTransformer {
038    private static final Logger LOG = Logger.getLogger(ContentTransformer.class);
039
040    private static final class LoggingErrorListener implements ErrorListener {
041        private final ErrorListener delegate;
042        public LoggingErrorListener(ErrorListener delegate) {
043            this.delegate = delegate;
044        }
045
046        public void error(TransformerException exception) throws TransformerException {
047            LOG.error("Error transforming document", exception);
048        }
049
050        public void fatalError(TransformerException exception) throws TransformerException {
051            if (delegate != null) {
052                delegate.fatalError(exception);
053            } else {
054                throw exception;
055            }
056            
057        }
058
059        public void warning(TransformerException exception) throws TransformerException {
060            LOG.warn("Error transforming document", exception);
061        }
062        
063    };
064
065    private Transformer transformer;
066
067    /**
068     * Constructs a ContentTransformer.java.
069     * @param aStyleSheet
070     * @throws Exception
071     */
072    public ContentTransformer(StreamSource aStyleSheet) throws Exception {
073        // create transformer        
074        TransformerFactory factory = TransformerFactory.newInstance();
075        transformer = factory.newTransformer( aStyleSheet );
076    }
077
078    /**
079     * Constructs a ContentTransformer.java.
080     * @param aStyleSheet
081     * @param parametermap
082     * @throws Exception
083     */
084    public ContentTransformer(StreamSource aStyleSheet, HashMap parametermap) throws Exception {
085       // create transformer
086       TransformerFactory factory = TransformerFactory.newInstance();
087       transformer = factory.newTransformer( aStyleSheet );
088       Iterator iter = parametermap.keySet().iterator();
089       while (iter.hasNext()) {
090          Object o = iter.next();
091          String param = o.toString();
092          String value = (String) parametermap.get(param);
093          transformer.setParameter(param, value);
094       }
095       transformer.setErrorListener(new LoggingErrorListener(transformer.getErrorListener()));
096    }
097
098    /**
099     * This method performs the actual transformation.
100     * @param xml
101     * @return
102     * @throws Exception
103     */
104    public String transform(String xml) throws Exception {
105
106        // perform transformation
107        Source xmlsource = new StreamSource(new StringReader(xml));
108        StringWriter sout = new StringWriter();
109         
110        transformer.transform(xmlsource, new StreamResult(sout));
111
112        // return resulting document
113        return sout.toString();
114    }
115}