{
List matchedTopics = new ArrayList( );
TopicSpace topicSpace = getTopicSpace( topicSpaceSet, topicPath );
if ( topicPath.getLocalPart( ).indexOf( "///" ) != -1 )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath
+ "' contains an empty path component." );
}
PathTokenizer pathTokenizer = new PathTokenizer( topicPath.getLocalPart( ) );
List topicSetsToSearch = new ArrayList( );
topicSetsToSearch.add( topicSpace );
boolean atFirstToken = true;
while ( pathTokenizer.hasMoreTokens( ) )
{
String pathToken = pathTokenizer.nextToken( );
matchedTopics.clear( );
for ( int i = 0; i < topicSetsToSearch.size( ); i++ )
{
TopicSet topicSetToSearch = (TopicSet) topicSetsToSearch.get( i );
boolean recurse = pathToken.startsWith( "/" );
String name = recurse ? pathToken.substring( 1 ) : pathToken;
matchedTopics.addAll( findTopics( topicSetToSearch, name, recurse ) );
}
if ( atFirstToken && matchedTopics.isEmpty( ) )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath
+ "' refers to a root topic that is not defined in the referenced topic space." );
}
topicSetsToSearch.clear( );
topicSetsToSearch.addAll( matchedTopics );