Package org.jostraca.process

Source Code of org.jostraca.process.GenericCompiler

/*
* Name:    GenericCompiler
* Authors: Richard Rodger
*
* Copyright (c) 2004 Richard Rodger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/


// package
package org.jostraca.process;


// import
import org.jostraca.Property;
import org.jostraca.Template;
import org.jostraca.UserText;

import org.jostraca.util.PropertySet;
import org.jostraca.util.Standard;
import org.jostraca.util.TextUtil;
import org.jostraca.util.BasicWayPoint;
import org.jostraca.util.WayPointRecorder;
import org.jostraca.util.ExecutableCommand;

import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import java.io.File;


/** Processing class for generic compilation using an external compiler.
*/
public class GenericCompiler extends TemplateHandlerSupport {


  public GenericCompiler() {
    // do nothing
  }


  protected void processImpl( Template pTemplate ) {
   
  }


  protected void completeImpl( List pTemplateList ) {
    List tmlist = pTemplateList;

    // sort each template into an equivalent compile operation
    HashMap compileBag = new HashMap();

    for( Iterator tmT = tmlist.iterator(); tmT.hasNext(); ) {
      Template tm      = (Template) tmT.next();
      String   bagname = resolveBagName( tm );

      ArrayList bagtmlist = null;
      if( !compileBag.containsKey( bagname ) ) {
        bagtmlist = new ArrayList();
        compileBag.put( bagname, bagtmlist );
      }
      else {
        bagtmlist = (ArrayList) compileBag.get( bagname );
      }

      bagtmlist.add( tm );
    }

    for( Iterator bagT = compileBag.keySet().iterator(); bagT.hasNext(); ) {
      String    bagname   = (String) bagT.next();
      ArrayList bagtmlist = (ArrayList) compileBag.get( bagname );
      if( 0 < bagtmlist.size() ) {
        compileAsFirst( bagtmlist );
      }
    }

  }



  protected String resolveBagName( Template pTemplate ) {
    Template    tm   = pTemplate;
    PropertySet tmps = tm.getMergedPropertySet();

    StringBuffer bagname = new StringBuffer();
    bagname.append( " "+tmps.get( Property.main_ExternalCompiler ) );
    bagname.append( " "+tmps.get( Property.main_ExternalCompilerOptions ) );

    return bagname.toString();
  }



  // compile using props from first tm
  protected void compileAsFirst( List pTemplateList ) {
    List        tmlist  = pTemplateList;
    Template    firsttm = (Template) pTemplateList.get(0);
    PropertySet tmps    = firsttm.getMergedPropertySet();

    boolean successful = false;
    boolean compile    = false;
    StringBuffer sourceFilesB = new StringBuffer();
    for( Iterator tmT = tmlist.iterator(); tmT.hasNext(); ) {
      Template tm  = (Template) tmT.next();

      File executablePath = makeExecutablePath( tm );
      tm.setCodeWriterExecutablePath( executablePath );

      boolean compileRequired = compileRequired( tm );

      if( compileRequired ) {
        File cwF = tm.getCodeWriterPath();
        sourceFilesB.append( " "+TextUtil.quoteSpaces( cwF.getPath() ) );
        WayPointRecorder.add( BasicWayPoint.CompilingCodeWriter.make( cwF.getAbsolutePath() ) );
        compile = true;
      }
    }

    if( compile ) {
      String sourceFiles  = sourceFilesB.toString();
      String compiler     = tmps.get( Property.main_ExternalCompiler );
      String compilerOpts = tmps.get( Property.main_ExternalCompilerOptions );

      ExecutableCommand cmd = new ExecutableCommand( compiler, compilerOpts, sourceFiles );
      String fullcmd = cmd.getFullCmd();

      cmd.setUserMessageHandler( iUserMessageHandler );
      cmd.setActivityDescription( UserText.get( UserText.TXT_compiling ) );

      successful = cmd.execute();

      if( !successful ) {
        if( cmd.hasErrResult() ) {
          throw ProcessException.CODE_compile_errors( cmd.getExecutedCmd() + Standard.NEWLINE
                                                       + cmd.getOutResult() + Standard.NEWLINE
                                                       + cmd.getErrResult() + Standard.NEWLINE
                                                       );
        }
        else if( cmd.wasNotFound() ) {
          throw ProcessException.CODE_compiler_not_found( compiler );
        }
        else {
          throw ProcessException.CODE_compile_failed( cmd.getExecutedCmd() + Standard.NEWLINE
                                                       + cmd.getOutResult() + Standard.NEWLINE
                                                       + cmd.getErrResult() + Standard.NEWLINE
                                                       );
        }
      }
    }
  }


  protected boolean compileRequired( Template pTemplate ) {
    try {
      Template     tm              = pTemplate;
      boolean      compileRequired = true;
      PropertySet  tmps            = tm.getMergedPropertySet();
      StringBuffer reason          = new StringBuffer();
      File         executablePath  = pTemplate.getCodeWriterExecutablePath();

      // definitely compile
      if( tmps.isYes( Property.main_CompileCodeWriter ) ) {
        compileRequired = true;
        reason.append( "main.CompileCodeWriter="+tmps.get( Property.main_CompileCodeWriter ) );
      }

      // definitely do not compile
      else if( tmps.isNo( Property.main_CompileCodeWriter ) ) {
        compileRequired = false;
        reason.append( "main.CompileCodeWriter="+tmps.get( Property.main_CompileCodeWriter ) );
      }

      // otherwise, compile only if needed
      else if( tmps.isYes( Property.lang_HasExecutable ) ) {

        // no executable => definitely compile
        if( ! executablePath.exists() ) {
          compileRequired = true;
          reason.append( "executable not found: "+executablePath );
        }

        // code writer changed => definitely compile
        else if( tm.getCodeWriterChanged() ) {
          compileRequired = true;
          reason.append( "CodeWriter changed" );
        }
       
        // no changes, so use the existing executable
        else {
          compileRequired = false;
          reason.append( "no changes found" );
        }
      }
   
      else {
        compileRequired = false;
        reason.append( "no executable" );
      }

     
      iUserMessageHandler.debug( "Compile Required:", ""+compileRequired+" ("+reason+")" );

      return compileRequired;
    }
    catch( Exception e ) {
      throw new ProcessException( e );
    }
  }


  protected File makeExecutablePath( Template pTemplate ) {
    File cwep = pTemplate.getCodeWriterExecutablePath();
    return cwep;
  }

}




TOP

Related Classes of org.jostraca.process.GenericCompiler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.