/*=============================================================================*
* 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.v2004_06;
import org.apache.ws.notification.topics.Topic;
import org.apache.ws.notification.topics.TopicNamespace;
import org.apache.ws.notification.topics.TopicSiblingSet;
import org.apache.ws.notification.topics.TopicsTypeFactory;
import org.apache.ws.notification.topics.TopicsTypeReader;
import org.apache.ws.notification.topics.expression.ConcreteTopicExpression;
import org.apache.ws.notification.topics.expression.FullTopicExpression;
import org.apache.ws.notification.topics.expression.InvalidTopicExpressionException;
import org.apache.ws.notification.topics.expression.SimpleTopicExpression;
import org.apache.ws.notification.topics.expression.TopicExpression;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.xml.NamespaceContext;
import org.apache.ws.util.xml.impl.XmlBeansNamespaceContext;
import org.apache.xmlbeans.XmlObject;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSBaseNotification12Draft01.TopicExpressionDocument;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSBaseNotification12Draft01.TopicExpressionType;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSTopics12Draft01.TopicSpaceDocument;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSTopics12Draft01.TopicSpaceType;
import org.oasisOpen.docs.wsn.x2004.x06.wsnWSTopics12Draft01.TopicType;
import javax.xml.namespace.QName;
import java.util.StringTokenizer;
/**
* A topics type reader for the 2004/06 version of the WS-Topics specification.
*/
public class TopicsTypeReaderImpl
extends TopicsTypeReader
{
/**
* DOCUMENT_ME
*
* @param xBean DOCUMENT_ME
*
* @return DOCUMENT_ME
*
* @throws InvalidTopicExpressionException DOCUMENT_ME
* @throws IllegalStateException DOCUMENT_ME
*/
public TopicExpression toTopicExpression( XmlObject xBean )
throws InvalidTopicExpressionException
{
TopicExpressionType topicExprType = toTopicExpressionType( xBean );
if ( !topicExprType.isSetDialect( ) )
{
throw new IllegalStateException( "The Dialect attribute is required by the WS-BaseNotification TopicExpressionType." );
}
String dialect = topicExprType.getDialect( );
TopicExpression topicExpr;
if ( dialect.equals( TopicsConstants.TOPIC_EXPR_DIALECT_SIMPLE ) )
{
topicExpr = new SimpleTopicExpression( XmlBeanUtils.getValueAsQName( topicExprType ) );
}
else if ( dialect.equals( TopicsConstants.TOPIC_EXPR_DIALECT_CONCRETE ) )
{
topicExpr = new ConcreteTopicExpression( XmlBeanUtils.getValueAsQName( topicExprType ) );
}
else if ( dialect.equals( TopicsConstants.TOPIC_EXPR_DIALECT_FULL ) )
{
String expr = XmlBeanUtils.getValue( topicExprType );
StringTokenizer tokenizer = new StringTokenizer( expr, "|" );
QName[] topicPaths = new QName[tokenizer.countTokens( )];
int i = 0;
while ( tokenizer.hasMoreTokens( ) )
{
topicPaths[i++] = toQName( tokenizer.nextToken( ),
new XmlBeansNamespaceContext( topicExprType ) );
}
topicExpr = new FullTopicExpression( topicPaths );
}
else
{
throw new IllegalStateException( "Unknown TopicExpression dialect: " + dialect );
}
return topicExpr;
}
/**
* DOCUMENT_ME
*
* @param xBean DOCUMENT_ME
*
* @return DOCUMENT_ME
*/
public TopicNamespace toTopicNamespace( XmlObject xBean )
{
TopicSpaceType topicSpaceType = toTopicSpaceType( xBean );
// TODO: validate the TopicSpaceType
TopicNamespace topicNs =
TopicsTypeFactory.newInstance( ).createTopicNamespace( topicSpaceType.getTargetNamespace( ) );
topicNs.setName( topicSpaceType.getName( ) );
importTopics( topicSpaceType.getTopicArray( ),
topicNs );
return topicNs;
}
private void importTopics( TopicType[] topicTypes,
TopicSiblingSet topicSiblingSet )
{
for ( int i = 0; i < topicTypes.length; i++ )
{
TopicType topicType = topicTypes[i];
Topic topic = topicSiblingSet.addTopic( topicType.getName( ) );
importTopics( topicType.getTopicArray( ),
topic ); // recurse
}
}
private QName toQName( String topicPath,
NamespaceContext nsContext )
throws InvalidTopicExpressionException
{
String prefix;
String localPart;
int i = topicPath.indexOf( ':' );
if ( i == -1 ) // no prefix
{
prefix = "";
localPart = topicPath;
}
else if ( i == 0 )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath + "' starts with a colon." );
}
else if ( i == ( topicPath.length( ) - 1 ) )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath + "' ends with a colon." );
}
else
{
prefix = topicPath.substring( 0, i );
localPart = topicPath.substring( i + 1 );
if ( localPart.indexOf( ':' ) != -1 )
{
throw new InvalidTopicExpressionException( "Local part of topic path '" + topicPath
+ "' contains a colon." );
}
}
String nsURI = nsContext.getNamespaceURI( prefix );
return new QName( nsURI, localPart, prefix );
}
private TopicExpressionType toTopicExpressionType( XmlObject xBean )
{
TopicExpressionType topicExpressionType;
try
{
topicExpressionType = (TopicExpressionType) xBean;
}
catch ( ClassCastException cce )
{
if ( xBean instanceof TopicExpressionDocument )
{
TopicExpressionDocument topicExpressionDoc = (TopicExpressionDocument) xBean;
topicExpressionType = topicExpressionDoc.getTopicExpression( );
}
else
{
throw new IllegalArgumentException( );
}
}
return topicExpressionType;
}
private TopicSpaceType toTopicSpaceType( XmlObject xBean )
{
TopicSpaceType topicSpaceType;
try
{
topicSpaceType = (TopicSpaceType) xBean;
}
catch ( ClassCastException cce )
{
if ( xBean instanceof TopicSpaceDocument )
{
TopicSpaceDocument topicSpaceDoc = (TopicSpaceDocument) xBean;
topicSpaceType = topicSpaceDoc.getTopicSpace( );
}
else
{
throw new IllegalArgumentException( );
}
}
return topicSpaceType;
}
}