/*=============================================================================*
* 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.notification.topics.expression.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.notification.topics.Topic;
import org.apache.ws.notification.topics.TopicSpaceSet;
import org.apache.ws.notification.topics.expression.InvalidTopicExpressionException;
import org.apache.ws.notification.topics.expression.TopicExpression;
import org.apache.ws.notification.topics.expression.TopicExpressionEngine;
import org.apache.ws.notification.topics.expression.TopicExpressionEvaluator;
import org.apache.ws.notification.topics.expression.TopicExpressionException;
import org.apache.ws.notification.topics.expression.TopicExpressionResolutionException;
import org.apache.ws.notification.topics.expression.TopicPathDialectUnknownException;
import org.apache.ws.resource.JndiConstants;
import org.apache.ws.util.jndi.JNDIUtils;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Resolves topic expressions over topic lists. The engine looks for topic expression evaluators under
* "wsrf/topic/eval" context.
*
* @see org.apache.ws.notification.topics.TopicSpaceSet
*/
public class TopicExpressionEngineImpl
implements TopicExpressionEngine
{
private static final Log LOG = LogFactory.getLog( TopicExpressionEngineImpl.class.getName( ) );
private Map m_evaluators = new HashMap( );
/**
* Creates a new {@link TopicExpressionEngineImpl} object.
*/
public TopicExpressionEngineImpl( )
{
this.refresh( );
}
/**
* Get the default topic expression engine instance (currently used to hide JNDI lookup details, may change in the
* future)
*
* @return The default topic expression engine instance
*/
public static TopicExpressionEngine getInstance( )
{
try
{
Context context = new InitialContext( );
return (TopicExpressionEngine) context.lookup( JndiConstants.KEY_NAME_DEFAULT_TOPIC_EXPRESSION_ENGINE );
}
catch ( NamingException ne )
{
LOG.warn( "topicEngineConfigError: " + ne );
return new TopicExpressionEngineImpl( );
}
}
/**
* DOCUMENT_ME
*
* @param dialect DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public synchronized TopicExpressionEvaluator getEvaluator( String dialect )
{
TopicExpressionEvaluator evaluator = (TopicExpressionEvaluator) this.m_evaluators.get( dialect );
return evaluator;
}
/**
* DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public synchronized String[] getSupportedDialects( )
{
return (String[]) this.m_evaluators.keySet( ).toArray( new String[this.m_evaluators.size( )] );
}
/**
* DOCUMENT_ME
*
* @param topicSpaceSet DOCUMENT_ME
* @param topicExpression DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws org.apache.ws.notification.topics.expression.TopicPathDialectUnknownException DOCUMENT_ME
* @throws TopicExpressionResolutionException DOCUMENT_ME
* @throws InvalidTopicExpressionException DOCUMENT_ME
* @throws TopicExpressionException DOCUMENT_ME
* @throws TopicPathDialectUnknownException DOCUMENT_ME
*/
public synchronized Topic[] evaluateTopicExpression( TopicSpaceSet topicSpaceSet,
TopicExpression topicExpression )
throws org.apache.ws.notification.topics.expression.TopicPathDialectUnknownException,
TopicExpressionResolutionException,
InvalidTopicExpressionException,
TopicExpressionException
{
if ( topicExpression == null )
{
throw new InvalidTopicExpressionException( "nullArgument" + "topicExpression" );
}
if ( topicExpression.getDialect( ) == null )
{
throw new org.apache.ws.notification.topics.expression.TopicPathDialectUnknownException( "nullArgument"
+ "topicExpression.dialect" );
}
String dialect = topicExpression.getDialect( ).toString( );
TopicExpressionEvaluator evaluator = getEvaluator( dialect );
if ( evaluator == null )
{
if ( LOG.isDebugEnabled( ) )
{
LOG.debug( "Dialect not supported:" + dialect );
LOG.debug( "Registered dialects are:" );
Iterator keyIterator = m_evaluators.keySet( ).iterator( );
Object key = null;
while ( keyIterator.hasNext( ) )
{
key = keyIterator.next( );
LOG.debug( key );
}
LOG.debug( "key.equals(dialect): " + ( key.equals( dialect.toString( ) ) ) );
LOG.debug( "this.evaluators.containsKey(dialect): "
+ this.m_evaluators.containsKey( dialect.toString( ) ) );
LOG.debug( "HashCode of key: " + String.valueOf( key.hashCode( ) ) );
LOG.debug( "HashCode of dialect: " + String.valueOf( dialect.toString( ).hashCode( ) ) );
LOG.debug( "Object stored for key: " + this.m_evaluators.get( key ) );
}
throw new TopicPathDialectUnknownException( "The dialect " + dialect + " was not recognized." );
}
return evaluator.evaluate( topicSpaceSet, topicExpression );
}
/**
* Refresh the set of registered topic expression evaluators using information discovered from the JNDI registry.
* This method removes any previously registered topic expression evaluators, so handle with care.
*/
public synchronized void refresh( )
{
m_evaluators.clear( );
NamingEnumeration list = null;
try
{
Context context = new InitialContext( );
list = context.list( JndiConstants.TOPIC_EXPRESSION_EVALUATOR_CONTEXT );
while ( list.hasMore( ) )
{
NameClassPair pair = (NameClassPair) list.next( );
TopicExpressionEvaluator evaluator =
(TopicExpressionEvaluator) JNDIUtils.lookup( context,
JndiConstants.TOPIC_EXPRESSION_EVALUATOR_CONTEXT + "/"
+ pair.getName( ), TopicExpressionEvaluator.class );
registerEvaluator( evaluator );
}
}
catch ( NamingException ne )
{
LOG.warn( "topicEngineInitError: " + ne );
registerEvaluator( new SimpleTopicExpressionEvaluator( ) );
registerEvaluator( new ConcreteTopicExpressionEvaluator( ) );
registerEvaluator( new FullTopicExpressionEvaluator( ) );
}
finally
{
if ( list != null )
{
try
{
list.close( );
}
catch ( NamingException ne )
{
}
}
}
}
/**
* DOCUMENT_ME
*
* @param evaluator DOCUMENT_ME
*/
public synchronized void registerEvaluator( TopicExpressionEvaluator evaluator )
{
LOG.debug( "Adding dialects for " + evaluator.getClass( ).getName( ) );
String[] dialects = evaluator.getDialects( );
for ( int i = 0; i < dialects.length; i++ )
{
LOG.debug( "Adding dialect: " + dialects[i] );
this.m_evaluators.put( dialects[i], evaluator );
}
}
}