/*=============================================================================*
* Copyright 2006 The Apache Software Foundation
*
* 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 org.apache.muse.core.platform.axis2;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.muse.core.AbstractEnvironment;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.MessageHeaders;
import org.apache.muse.ws.addressing.soap.SoapFault;
/**
*
* AxisEnvironment is a concrete{@linkplain org.apache.muse.core.Environment Environment}
* for the Apache Axis2 SOAP engine. It provides all of the lower-level
* functionality that is abstracted through the Environment interface using
* the local file system and Axis2 context APIs.
*
* @author Dan Jemiolo (danj)
*
*/
public class AxisEnvironment extends AbstractEnvironment
{
//
// The service installation directory (NOT the WAR file directory). This
// is found at $WAR_INSTALL_DIR/WEB-INF/services/muse
//
private File _realDirectory = null;
/**
*
* Converts Axis2's OperationContext into the Muse addressing context,
* MessageHeaders. Hopefully this becomes irrelevant through the
* adoption of something like JSR-261 or some WS-A project in Apache Commons.
*
*/
public static MessageHeaders convertContext(OperationContext opContext)
{
SOAPHeader axiom = getInputMessageContext(opContext).getEnvelope().getHeader();
Element dom = convertToDOM(axiom);
try
{
return new MessageHeaders(dom);
}
catch (SoapFault error)
{
throw new RuntimeException(error.getMessage(), error);
}
}
/**
*
* Converts Axis2's EPR type into our general one so that code isn't specific
* to the Axis2 platform. Hopefully this becomes irrelevant through the
* adoption of something like JSR-261 or some WS-A project in Apache Commons.
*
*/
public static EndpointReference convertEPR(org.apache.axis2.addressing.EndpointReference axisEPR)
{
URI address = URI.create(axisEPR.getAddress());
EndpointReference epr = new EndpointReference(address);
Map parameters = axisEPR.getAllReferenceParameters();
Iterator i = parameters.keySet().iterator();
while (i.hasNext())
{
QName name = (QName)i.next();
OMElement axiomValue = (OMElement)parameters.get(name);
Element domValue = convertToDOM(axiomValue);
epr.addParameter(domValue);
}
return epr;
}
/**
*
* Convert DOM to Axiom. Muse uses the DOM API in the JDK, Axis2 uses
* the Axiom API, which is similar but... different.
*
*/
public static OMElement convertToAxiom(Element xml)
{
String xmlString = XmlUtils.toString(xml, false);
byte[] xmlBytes = xmlString.getBytes();
StAXOMBuilder builder = null;
try
{
builder = new StAXOMBuilder(new ByteArrayInputStream(xmlBytes));
}
catch (XMLStreamException error)
{
throw new RuntimeException(error.getMessage(), error);
}
return builder.getDocumentElement();
}
/**
*
* Convert Axiom to DOM. Muse uses the DOM API in the JDK, Axis2 uses
* the Axiom API, which is similar but... different.
*
*/
public static Element convertToDOM(OMElement axiom)
{
try
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
axiom.serialize(output);
byte[] bytes = output.toByteArray();
ByteArrayInputStream input = new ByteArrayInputStream(bytes);
Document doc = XmlUtils.createDocument(input);
return XmlUtils.getFirstElement(doc);
}
catch (Throwable error)
{
throw new RuntimeException(error.getMessage(), error);
}
}
/**
*
* @param opContext
*
* @return The Axis2 MessageContext for the request.
*
*/
public static MessageContext getInputMessageContext(OperationContext opContext)
{
try
{
return opContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
}
catch (AxisFault error)
{
throw new RuntimeException(error.getMessage(), error);
}
}
/**
*
* @param opContext
*
* @return The Axis2 MessageContext for the response.
*
*/
public static MessageContext getOutputMessageContext(OperationContext opContext)
{
try
{
return opContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
}
catch (AxisFault error)
{
throw new RuntimeException(error.getMessage(), error);
}
}
/**
*
* This constructor determines the value of the "real directory" - where
* the application is installed on the file system so that it can read
* local files when it needs to.
*
* @param opContext
*
*/
public AxisEnvironment(OperationContext opContext)
{
MessageHeaders wsa = convertContext(opContext);
addAddressingContext(wsa);
MessageContext message = getInputMessageContext(opContext);
//
// where are we? this is the path of the service installation,
// not of the Axis2 WAR
//
String realDirPath = message.getAxisService().getFileName().getFile();
_realDirectory = new File(realDirPath);
String address = message.getTo().getAddress();
setDefaultURI(getDeploymentURI(address));
}
public URL getDataResource(String path)
{
File file = new File(_realDirectory, path);
try
{
return file.toURL();
}
catch (MalformedURLException error)
{
throw new RuntimeException(error);
}
}
public InputStream getDataResourceStream(String path)
{
File file = new File(getRealDirectory(), path);
try
{
return new FileInputStream(file);
}
catch (FileNotFoundException error)
{
throw new RuntimeException(error.getMessage(), error);
}
}
public EndpointReference getDeploymentEPR()
{
return getDefaultEPR();
}
public File getRealDirectory()
{
return _realDirectory;
}
}