/*=============================================================================*
* 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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.Soap1_1Constants;
import org.apache.ws.addressing.handler.WSAddressingHandler;
import org.apache.ws.resource.Resource;
import org.apache.ws.resource.ResourceContext;
import org.apache.ws.resource.ResourceException;
import org.apache.ws.resource.ResourceHome;
import org.apache.ws.resource.WsrfRuntime;
import org.apache.ws.resource.faults.FaultException;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.util.i18n.Messages;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPMessage;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* An implementation of a resource context.
*/
public class ResourceContextImpl
implements ResourceContext
{
private static final Log LOG = LogFactory.getLog( ResourceContextImpl.class.getName( ) );
private static final Messages MSG = MessagesImpl.getInstance( );
private SOAPMessage m_msg;
private ResourceHome m_home;
private String m_serviceName;
private URL m_serviceURL;
private Map m_propsMap = Collections.synchronizedMap( new HashMap( ) );
private String m_action;
private SOAPMessageContext m_msgContext;
/**
* Creates a new {@link ResourceContextImpl} object.
*
* @param soapMsgContext SOAP message context corresponding to a particular request
*/
public ResourceContextImpl( SOAPMessageContext soapMsgContext )
throws Exception
{
if ( soapMsgContext == null )
{
throw new IllegalArgumentException( MSG.getMessage( Keys.NULL_SOAPMSGCTX ) );
}
m_msgContext = soapMsgContext;
m_msg = soapMsgContext.getMessage( );
extractFields( soapMsgContext );
lookupHome( );
}
/**
* Creates a new {@link ResourceContextImpl} object.
*
* @throws Exception DOCUMENT_ME
*/
protected ResourceContextImpl( )
throws Exception
{
}
/**
* 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
*/
public String getRequestAction( )
{
return m_action;
}
/**
* @see org.apache.ws.resource.ResourceContext#getResource()
*/
public Resource getResource( )
throws ResourceException
{
ResourceHome home = getResourceHome( );
Object id = home.extractResourceIdentifier( this );
return home.find( id );
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public ResourceHome getResourceHome( )
{
return m_home;
}
/**
* @see ResourceContext#setResponseAction(java.net.URI)
*/
public void setResponseAction( URI action )
{
if ( action != null )
{
m_msgContext.setProperty( WSAddressingHandler.CONTEXT_PROP_WSA_RESPONSE_ACTION,
action.toString( ) );
}
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public SOAPMessage getSOAPMessage( )
{
return m_msg;
}
/**
* Returns target service name 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 service name associated with the
* underlying SOAP message 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 );
}
/**
* Returns the value of the WS-Addressing Action header element.
*
* @param msgContext the context for the current SOAP request; must not be null
*
* @return
*/
protected String getAddressingAction( SOAPMessageContext msgContext )
{
return WSAddressingHandler.getAddressingAction( msgContext );
}
/**
* DOCUMENT_ME
*
* @param serviceURL DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
protected String getBaseURL( URL serviceURL )
{
String s = serviceURL.toString( );
s = s.substring( 0,
s.lastIndexOf( "/" ) );
return s;
}
/**
* Sets the target m_serviceName of this context.
*
* @param serviceName m_serviceName name.
*/
protected void setServiceName( String serviceName )
{
m_serviceName = serviceName;
}
/**
* DOCUMENT_ME
*
* @param msgContext DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
protected String getServiceName( MessageContext msgContext )
{
URL serviceURL =
( m_serviceURL != null ) ? m_serviceURL : getServiceURL( (SOAPMessageContext) msgContext );
String serviceName = serviceURL.toString( );
serviceName = serviceName.substring( serviceName.lastIndexOf( "/" ) + 1 );
return serviceName;
}
/**
* DOCUMENT_ME
*
* @param serviceURL DOCUMENT_ME
*/
protected void setServiceURL( URL serviceURL )
{
m_serviceURL = serviceURL;
}
/**
* DOCUMENT_ME
*
* @param msgContext the context for the current SOAP request; must not be null
*
* @return DOCUMENT_ME
*/
protected URL getServiceURL( SOAPMessageContext msgContext )
{
String addressingTo = WSAddressingHandler.getAddressingTo( msgContext );
if ( addressingTo != null )
{
try
{
LOG.debug( MSG.getMessage( Keys.GET_SERVICE_URL_FROM_ADDR_HDR, addressingTo ) );
return new URL( addressingTo );
}
catch ( MalformedURLException murle )
{
LOG.debug( MSG.getMessage( Keys.INVALID_WSA_TO, addressingTo ) );
throw new FaultException( Soap1_1Constants.FAULT_CLIENT,
"The WS-Addressing destination specified in the SOAP header (i.e. wsa:To header element) is not a valid URI." );
}
}
return null; // should an exception be thrown here instead of returning null?
}
/**
* DOCUMENT_ME
*
* @param msgContext DOCUMENT_ME
*/
protected void extractProperties( MessageContext msgContext )
{
Iterator propertyNames = msgContext.getPropertyNames( );
while ( propertyNames.hasNext( ) )
{
String keyName = (String) propertyNames.next( );
m_propsMap.put( keyName,
msgContext.getProperty( keyName ) );
}
}
/**
* DOCUMENT_ME
*
* @throws Exception DOCUMENT_ME
*/
protected void lookupHome( )
throws Exception
{
m_home = WsrfRuntime.getRuntime( ).getResourceHome( getServiceName( ) );
initializeResourceHome( );
}
private void extractFields( SOAPMessageContext msgContext )
{
//extract the properties first so subclasses can look for platform specific props
extractProperties( msgContext );
m_action = getAddressingAction( msgContext );
m_serviceURL = getServiceURL( msgContext );
m_serviceName = getServiceName( msgContext );
}
private void initializeResourceHome( )
throws Exception
{
if ( m_home instanceof AbstractResourceHome )
{
AbstractResourceHome abstractResourceHome = ( (AbstractResourceHome) m_home );
synchronized ( abstractResourceHome )
{
if ( !abstractResourceHome.isInitialized( ) )
{
abstractResourceHome.init( );
}
}
}
}
}