/*=============================================================================*
* Copyright 2004 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.ws.resource.impl;
import org.apache.axis.message.addressing.AddressingHeaders;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.resource.JndiConstants;
import org.apache.ws.resource.NoResourceHomeException;
import org.apache.ws.resource.Resource;
import org.apache.ws.resource.ResourceContext;
import org.apache.ws.resource.ResourceContextException;
import org.apache.ws.resource.ResourceException;
import org.apache.ws.resource.ResourceHome;
import org.apache.ws.resource.ResourceKey;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.faults.ResoureKeyHeaderNotFoundFaultException;
import org.apache.ws.util.i18n.Messages;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.lang.reflect.Constructor;
/**
* LOG-DONE
* DOCUMENT_ME
*/
public abstract class AbstractResourceContext
extends ResourceContext
{
private static final Log LOG = LogFactory.getLog( AbstractResourceContext.class.getName() );
public static final Messages MSG = MessagesImpl.getInstance();
private SOAPMessage m_msg;
private ResourceHome m_home;
private String m_homeLocation;
private String m_serviceName;
private URL m_serviceURL;
private Map m_propsMap = Collections.synchronizedMap( new HashMap() );
private String m_resourceKeyQname;
private Class m_resourceKeyClass;
private ResourceKey m_resourceKey;
/**
* Creates a new {@link AbstractResourceContext} object.
*
* @param soapMsgContext DOCUMENT_ME
*/
public AbstractResourceContext( SOAPMessageContext soapMsgContext )
{
if ( soapMsgContext == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_SOAPMSGCTX ));
}
m_msg = soapMsgContext.getMessage();
extractFields( soapMsgContext );
}
/**
* Creates a new {@link AbstractResourceContext} object.
*
* @param soapMsgContext DOCUMENT_ME
* @param msg DOCUMENT_ME
*/
public AbstractResourceContext( SOAPMessageContext soapMsgContext,
SOAPMessage msg )
{
if ( soapMsgContext == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_SOAPMSGCTX) );
}
extractFields( soapMsgContext );
m_msg = msg;
}
/**
* DOCUMENT_ME
*
* @param name DOCUMENT_ME
* @param value DOCUMENT_ME
*/
public void setProperty( String name,
Object value )
{
m_propsMap.put( name, value );
}
/**
* DOCUMENT_ME
*
* @param name DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public Object getProperty( String name )
{
return this.m_propsMap.get( name );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public Iterator getPropertyNames()
{
return this.m_propsMap.keySet().iterator();
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws ResourceContextException DOCUMENT_ME
* @throws ResourceException DOCUMENT_ME
*/
public Resource getResource()
throws ResourceContextException,
ResourceException
{
ResourceHome home = getResourceHome();
Class resourceKeyClass = null;
String resourceKeyClassName = null;
try
{
resourceKeyClassName = home.getResourceKeyClassName();
resourceKeyClass = Class.forName(resourceKeyClassName);
}
catch (ClassNotFoundException e)
{
throw new ResourceException(e);
}
ResourceKey key = getResourceKey( QName.valueOf(home.getResourceKeyName()), resourceKeyClass);
LOG.debug( MSG.getMessage( Keys.LOOKUP_RESOURCE_FOR_KEY, key.getValue()));
Resource resource = home.find( key );
LOG.debug( MSG.getMessage( Keys.FOUND_RESOURCE, resource ));
return resource;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws NoResourceHomeException DOCUMENT_ME
* @throws ResourceContextException DOCUMENT_ME
*/
public synchronized ResourceHome getResourceHome()
throws ResourceContextException
{
if ( m_home == null )
{
try
{
m_home = (ResourceHome) new InitialContext().lookup( getResourceHomeLocation() );
}
catch ( NamingException ne )
{
ne.printStackTrace( );
throw new ResourceContextException( ne );
}
}
return m_home;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public synchronized String getResourceHomeLocation()
{
if ( m_homeLocation == null )
{
m_homeLocation = JndiConstants.CONTEXT_NAME_SERVICES + "/" + getServiceName() + "/" + JndiConstants.ATOMIC_NAME_HOME;
}
LOG.debug(MSG.getMessage( Keys.JNDI_HOME_LOCATION,m_homeLocation));
return m_homeLocation;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws ResourceContextException DOCUMENT_ME
*/
public ResourceKey getResourceKey()
throws ResourceContextException
{
if ( m_resourceKey == null )
{
ResourceHome resourceHome = getResourceHome();
Class resourceKeyClass = null;
String resourceKeyClassName = null;
try
{
resourceKeyClassName = resourceHome.getResourceKeyClassName();
resourceKeyClass = Class.forName(resourceKeyClassName);
}
catch (ClassNotFoundException e)
{
throw new ResourceContextException(e);
}
String resourceKeyName = resourceHome.getResourceKeyName();
QName resourceKeyQName = resourceKeyName != null ? QName.valueOf(resourceKeyName) : null;
m_resourceKey = getResourceKey( resourceKeyQName,resourceKeyClass);
}
LOG.debug(MSG.getMessage( Keys.RESOURCE_KEY, String.valueOf(m_resourceKey)));
return m_resourceKey;
}
/**
* Creates a resource key for the current request.
*
* @param keyName DOCUMENT_ME
* @param keyClass DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws ResourceContextException DOCUMENT_ME
*/
public ResourceKey getResourceKey( QName keyName,
Class keyClass )
throws ResourceContextException,
ResoureKeyHeaderNotFoundFaultException
{
if ( keyName == null )
{
LOG.debug( MSG.getMessage( Keys.NULL_RESOURCE_NAME) );
return null;
}
SOAPHeaderElement headerElem = getResourceKeyHeader( keyName );
if ( headerElem == null )
{
throw new ResoureKeyHeaderNotFoundFaultException( keyName );
}
try
{
Constructor constructor = keyClass.getConstructor(new Class[]{SOAPHeaderElement.class});
return (ResourceKey)constructor.newInstance(new Object[]{headerElem});
}
catch ( Exception e )
{
throw new ResourceContextException( e );
}
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws ResourceContextException DOCUMENT_ME
*/
public SOAPHeaderElement getResourceKeyHeader()
throws ResourceContextException
{
ResourceHome home = getResourceHome();
QName keyName = QName.valueOf(home.getResourceKeyName());
return ( keyName == null ) ? null : getResourceKeyHeader( keyName );
}
/**
* DOCUMENT_ME
*
* @param keyName DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws ResourceContextException DOCUMENT_ME
*/
public SOAPHeaderElement getResourceKeyHeader( QName keyName )
throws ResourceContextException
{
try
{
return AbstractResourceContext.getResourceKeyHeader( this.m_msg, keyName, null );
}
catch ( SOAPException e )
{
throw new ResourceContextException( e );
}
}
/**
* DOCUMENT_ME
*
* @param msg DOCUMENT_ME
* @param keyName DOCUMENT_ME
* @param actorURI DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws SOAPException DOCUMENT_ME
* @throws IllegalArgumentException DOCUMENT_ME
*/
public static SOAPHeaderElement getResourceKeyHeader( SOAPMessage msg,
QName keyName,
String actorURI )
throws SOAPException
{
LOG.debug(MSG.getMessage( Keys.GET_RESOURCEKEY_HEADER, keyName.toString()));
if ( msg == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_SOAPMSGCTX) );
}
if ( keyName == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_RESOURCEKEY_QNAME) );
}
SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
SOAPHeader header = env.getHeader();
if ( header == null )
{
return null;
}
Iterator iter = header.examineHeaderElements( actorURI );
while ( iter.hasNext() )
{
SOAPHeaderElement headerElem = (SOAPHeaderElement) iter.next();
Name headerName = headerElem.getElementName();
if ( headerName.getLocalName().equals( keyName.getLocalPart() )
&& headerName.getURI().equals( keyName.getNamespaceURI() ) )
{
// found my header element;
return headerElem;
}
}
return null;
}
/**
* DOCUMENT_ME
*
* @param resourceKeyClass DOCUMENT_ME
*/
public void setResourceKeyClass( Class resourceKeyClass )
{
m_resourceKeyClass = resourceKeyClass;
}
/**
* DOCUMENT_ME
*
* @param resourceKeyQname DOCUMENT_ME
*/
public void setResourceKeyQname( String resourceKeyQname )
{
m_resourceKeyQname = resourceKeyQname;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public SOAPMessage getSOAPMessage()
{
return m_msg;
}
/**
* Returns target m_serviceName associated with this context.
*
* @return the target m_serviceName that was set with {@link #setServiceName(String) setService()}. If set to
* <code>null</code> or not set at all, by default it returns the target m_serviceName associated with the
* underlying SOAP m_msg context.
*/
public String getServiceName()
{
return m_serviceName;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public URL getServiceURL()
{
return m_serviceURL;
}
/**
* DOCUMENT_ME
*
* @param name DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public boolean containsProperty( String name )
{
return this.m_propsMap.containsKey( name );
}
/**
* DOCUMENT_ME
*
* @param name DOCUMENT_ME
*/
public void removeProperty( String name )
{
this.m_propsMap.remove( name );
}
/**
* Sets the target m_serviceName of this context.
*
* @param serviceName m_serviceName name.
*/
protected void setServiceName( String serviceName )
{
m_serviceName = serviceName;
// reset in case
synchronized ( this )
{
m_home = null;
m_homeLocation = null;
}
}
/**
* DOCUMENT_ME
*
* @param msgContext DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
protected String getServiceName( MessageContext msgContext )
{
URL serviceURL = ( m_serviceURL != null ) ? m_serviceURL : getServiceURL();
return serviceURL.getFile();
}
/**
* DOCUMENT_ME
*
* @param msgContext DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
protected URL getServiceURL( MessageContext msgContext )
{
if ( msgContext == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_MSGCTX ));
}
AddressingHeaders addrHeaders =
(AddressingHeaders) msgContext.getProperty( org.apache.axis.message.addressing.Constants.ENV_ADDRESSING_REQUEST_HEADERS );
try
{
String serviceUrl = addrHeaders.getTo().toString();
LOG.debug(MSG.getMessage( Keys.GET_SERVICE_URL_FROM_ADDR_HDR, serviceUrl));
return new URL( serviceUrl );
}
catch ( MalformedURLException murle )
{
throw new JAXRPCException( murle );
}
}
private void extractFields( MessageContext msgContext )
{
m_serviceURL = getServiceURL( msgContext );
m_serviceName = getServiceName( msgContext );
extractProperties( msgContext );
}
private void extractProperties( MessageContext msgContext )
{
Iterator propertyNames = msgContext.getPropertyNames();
while ( propertyNames.hasNext() )
{
String keyName = (String) propertyNames.next();
m_propsMap.put( keyName,
msgContext.getProperty( keyName ) );
}
}
}