Index: src/main/java/org/apache/camel/spring/Main.java =================================================================== --- src/main/java/org/apache/camel/spring/Main.java (revision 643013) +++ src/main/java/org/apache/camel/spring/Main.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.camel.spring; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -33,6 +34,7 @@ import org.apache.camel.view.RouteDotGenerator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -52,6 +54,7 @@ private long duration = -1; private TimeUnit timeUnit = TimeUnit.MILLISECONDS; private String dotOutputDir; + private boolean aggregateDot; private List routeBuilders = new ArrayList(); private List camelContexts = new ArrayList(); @@ -76,6 +79,14 @@ setDotOutputDir(parameter); } }); + addOption( new ParameterOption( "ad", "aggregate-dot", + "Aggregates all routes (in addition to individual route generation) into one context to create one monolithic DOT file for visual representations the entire system.", + "aggregate-dot" ) { + + protected void doProcess( String arg, String parameter, LinkedList remainingArgs ) { + setAggregateDot( "true".equals( parameter ) ); + } + } ); addOption(new ParameterOption( "d", "duration", @@ -352,20 +363,63 @@ for (Map.Entry entry : entries) { String name = entry.getKey(); SpringCamelContext camelContext = entry.getValue(); - camelContexts.add(camelContext); + camelContexts.add( camelContext ); + generateDot( name, camelContext, size ); + postProcesCamelContext( camelContext ); + } + + if (isAggregateDot()) { - String outputDir = dotOutputDir; - if (ObjectHelper.isNotNullAndNonEmpty(outputDir)) { - if (size > 1) { - outputDir += "/" + name; - } - RouteDotGenerator generator = new RouteDotGenerator(outputDir); - LOG.info("Generating DOT file for routes: " + outputDir + " for: " + camelContext - + " with name: " + name); - generator.drawRoutes(camelContext); + generateDot( "aggregate", aggregateSpringCamelContext( applicationContext ), 1 ); + } + } + + protected void generateDot( String name, SpringCamelContext camelContext, int size ) throws IOException { + + String outputDir = dotOutputDir; + if (ObjectHelper.isNotNullAndNonEmpty( outputDir )) { + if (size > 1) { + outputDir += "/" + name; + } + RouteDotGenerator generator = new RouteDotGenerator( outputDir ); + LOG.info( "Generating DOT file for routes: " + outputDir + " for: " + camelContext + " with name: " + name ); + generator.drawRoutes( camelContext ); + } + } + + /** + * Used for aggregate dot generation + * + * @param applicationContext + * @return + * @throws Exception + */ + private static SpringCamelContext aggregateSpringCamelContext( ApplicationContext applicationContext ) throws Exception { + + SpringCamelContext aggregateCamelContext = new SpringCamelContext() { + + /** + * Don't actually start this, it is merely fabricated for dot generation. + * @see org.apache.camel.impl.DefaultCamelContext#shouldStartRoutes() + */ + protected boolean shouldStartRoutes() { + + return false; } - postProcesCamelContext(camelContext); + }; + + // look up all configured camel contexts + String[] names = applicationContext.getBeanNamesForType( SpringCamelContext.class ); + for (String name : names) { + + SpringCamelContext next = (SpringCamelContext) applicationContext.getBean( name, SpringCamelContext.class ); + // aggregateCamelContext.addRoutes( next.getRoutes() ); + aggregateCamelContext.addRouteDefinitions( next.getRouteDefinitions() ); } + // Don't actually start this, it is merely fabricated for dot generation. + // answer.setApplicationContext( applicationContext ); + // answer.afterPropertiesSet(); + return aggregateCamelContext; } protected void postProcesCamelContext(CamelContext camelContext) throws Exception { @@ -388,4 +442,14 @@ } return ""; } + + private void setAggregateDot( boolean aggregateDot ) { + + this.aggregateDot = aggregateDot; + } + + private boolean isAggregateDot() { + + return aggregateDot; + } }