/*
* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.dataservices.core;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.jaxp.OMSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.dataservices.common.DBConstants;
import org.wso2.carbon.dataservices.core.internal.DataServicesDSComponent;
import org.wso2.carbon.dataservices.core.listeners.RegistryServiceListener;
import org.wso2.carbon.registry.core.service.RegistryService;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**
* This class is used in transforming data services result using XSLT.
*/
public class XSLTTransformer implements RegistryServiceListener {
private static final Log log = LogFactory.getLog(DBUtils.class);
private String xsltPath;
private Transformer transformer;
private XMLInputFactory xmlInputFactory;
private int tenantId;
public XSLTTransformer(String xsltPath) throws TransformerConfigurationException,
DataServiceFault, IOException {
this.xsltPath = xsltPath;
/* set tenant id */
this.tenantId = DBUtils.getDeploymentTimeTenantId();
if (xsltPath.startsWith(DBConstants.CONF_REGISTRY_PATH_PREFIX) ||
xsltPath.startsWith(DBConstants.GOV_REGISTRY_PATH_PREFIX)) {
DataServicesDSComponent.registerRegistryServiceListener(this);
} else {
TransformerFactory tFactory = TransformerFactory.newInstance();
this.transformer = tFactory.newTransformer(
new StreamSource(DBUtils.getInputStreamFromPath(this.getXsltPath())));
}
this.xmlInputFactory = XMLInputFactory.newInstance();
}
/**
* Read the XSLT file from the registry, when the service
* becomes active.
*/
public void setRegistryService(RegistryService registryService) {
TransformerFactory tFactory = TransformerFactory.newInstance();
try {
this.transformer = tFactory.newTransformer(new StreamSource(DBUtils
.getInputStreamFromPath(this.getXsltPath())));
} catch (Exception e) {
log.error("Error getting XSLT path from the registry", e);
}
}
public String getXsltPath() {
return xsltPath;
}
public Transformer getTransformer() {
return transformer;
}
public XMLInputFactory getXmlInputFactory() {
return xmlInputFactory;
}
/**
* Transforms the given XML element using the current XSLT transformer and
* returns the result.
*
* @param inputXML The XML data to be transformed
* @return The transformed XML
* @throws DataServiceFault
*/
public OMElement transform(OMElement inputXML) throws DataServiceFault {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Source xmlSource = new OMSource(inputXML);
if (this.getTransformer() != null) {
this.getTransformer().transform(xmlSource, new StreamResult(outputStream));
} else {
throw new DataServiceFault("XSLT transformer not initialized");
}
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
XMLStreamReader reader = this.getXmlInputFactory().createXMLStreamReader(inputStream);
StAXOMBuilder builder = new StAXOMBuilder(reader);
return builder.getDocumentElement();
} catch (Exception e) {
String msg = "Error in transforming with XSLT: " + e.getMessage();
log.error(msg, e);
throw new DataServiceFault(e, msg);
}
}
@Override
public int getTenantId() {
return tenantId;
}
}