All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.processpuzzle.maven.plugin.fitnesse.util.FitNesseHelper Maven / Gradle / Ivy

The newest version!
package com.processpuzzle.maven.plugin.fitnesse.util;

import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.logging.Log;

import com.google.common.collect.Lists;
import com.processpuzzle.maven.plugin.fitnesse.mojo.Launch;

import fitnesse.Shutdown;
import fitnesseMain.Arguments;
import fitnesseMain.FitNesseMain;

public class FitNesseHelper {
   public static final String DEFAULT_ROOT = "FitNesseRoot";
   private static final String UTF8 = "UTF-8";
   private static final long SHUTDOWN_WAIT_MS = 50;
   private final Log log;

   public FitNesseHelper( final Log log ) {
      this.log = log;
   }

   /**
    * Note: Through experiment I've found that we can safely send duplicate 'create SymLink' requests - FitNesse isn't bothered But We use a HashSet to
    * eliminate duplicate top-level link names anyway, just to keep the output clean
    * 
    * @throws IOException
    * @see FitNesse SymLink User Guide
    */
   public void createSymLink( final File basedir, final String testResourceDirectory, final int port, final Launch... launches ) throws IOException {
      final Set linkNames = new HashSet();
      for( final Launch launch : launches ){
         linkNames.add( calcLinkName( launch ) );
      }
      for( final String linkName : linkNames ){
         createSymLink( basedir, testResourceDirectory, port, linkName );
      }
   }

   public StringBuilder formatAndAppendClasspathArtifact( final StringBuilder wikiFormatClasspath, final Artifact artifact ) {
      return formatAndAppendClasspath( wikiFormatClasspath, artifact.getFile().getPath() );
   }

   public StringBuilder formatAndAppendClasspath( final StringBuilder wikiFormatClasspath, final String path ) {
      if( Utils.whitespaceSituation( path ) ){
         log.error( Utils.whitespaceWarning( path, "FitNesse classpath may not function correctly in wiki mode" ) );
      }
      wikiFormatClasspath.append( "!path " );
      wikiFormatClasspath.append( path );
      wikiFormatClasspath.append( "\n" );
      return wikiFormatClasspath;
   }

   public void launchFitNesseServer( final String port, final String workingDir, final String root, final String logDir ) throws Exception {
      ArrayList commandLineArguments = Lists.newArrayList( "-e", "0", "-o", "-p", String.valueOf( port ), "-d", workingDir, "-r", root );
      
      if( logDir != null && !logDir.trim().equals( "" ) ){
         commandLineArguments.add( "-l" );
         commandLineArguments.add( logDir );
      }

      Arguments arguments = null;
      try{
         arguments = new Arguments( commandLineArguments.toArray( new String[commandLineArguments.size()] ));
      }catch( IllegalArgumentException e ){
         //Arguments.printUsage();
         exit( 1 );
      }
      Integer exitCode = 0;
      try{
         exitCode = new FitNesseMain().launchFitNesse( arguments );
      }catch( Exception e ){
         e.printStackTrace( System.out );
         exitCode = 1;
      }
      if( exitCode != null ){
         exit( exitCode );
      }
   }

   public void shutdownFitNesseServer( final String port ) {
      try{
         Shutdown.main( new String[] { "-p", port } );
         // Pause to give it a chance to shutdown
         Thread.sleep( SHUTDOWN_WAIT_MS );
      }catch( ConnectException e ){
         // If we get this specific exception,
         // we assume FitNesse is already not running
         this.log.info( "FitNesse already not running." );
      }catch( Exception e ){
         this.log.error( e );
      }
   }

   private int createSymLink( final File basedir, final String testResourceDirectory, final int port, final String linkName ) throws IOException {
      final String linkPath = calcLinkPath( linkName, basedir, testResourceDirectory );

      HttpURLConnection connection = null;
      try{
         final String urlPath = String.format( "/root?responder=symlink&linkName=%s&linkPath=%s&submit=%s", URLEncoder.encode( linkName, UTF8 ), URLEncoder.encode( linkPath, UTF8 ),
               URLEncoder.encode( "Create/Replace", UTF8 ) );
         final URL url = new URL( "http", "localhost", port, urlPath );
         this.log.info( "Calling " + url );
         connection = (HttpURLConnection) url.openConnection();
         connection.setRequestMethod( "GET" );
         connection.connect();
         final int responseCode = connection.getResponseCode();
         this.log.info( "Response code: " + responseCode );
         return responseCode;
      }finally{
         if( connection != null ){
            connection.disconnect();
         }
      }
   }

   private String calcLinkName( final Launch launch ) {
      final String linkName = StringUtils.substringBefore( launch.getPageName(), "." );
      return linkName;
   }

   /**
    * We want File.toURL() exactly because it doesn't properly encode URI's, otherwise we end up encoding parts of the returned linkPath twice.
    */
   @SuppressWarnings( "deprecation" )
   private String calcLinkPath( final String linkName, final File basedir, final String testResourceDirectory ) throws MalformedURLException {
      final StringBuilder linkPath = new StringBuilder( basedir.toURL().toString().replaceFirst( "/[A-Z]:", "" ).replaceFirst( ":", "://" ) );
      if( !linkPath.substring( linkPath.length() -1 ).equals( "/" )) {
         linkPath.append( "/" );
      }
      linkPath.append( testResourceDirectory );
      if( !linkPath.substring( linkPath.length() -1 ).equals( "/" )) {
         linkPath.append( "/" );
      }
      linkPath.append( linkName );
      return linkPath.toString();
   }
   
   private void exit( int exitCode ) {
      System.exit( exitCode );
   }   
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy