Home » apache-ant-1.7.1-src » org.apache.tools » ant » taskdefs » compilers » [javadoc | source]
    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    *
   17    */
   18   
   19   package org.apache.tools.ant.taskdefs.compilers;
   20   
   21   import org.apache.tools.ant.BuildException;
   22   import org.apache.tools.ant.Project;
   23   import org.apache.tools.ant.Task;
   24   import org.apache.tools.ant.util.ClasspathUtils;
   25   import org.apache.tools.ant.util.JavaEnvUtils;
   26   
   27   /**
   28    * Creates the necessary compiler adapter, given basic criteria.
   29    *
   30    * @since Ant 1.3
   31    */
   32   public final class CompilerAdapterFactory {
   33       private static final String MODERN_COMPILER = "com.sun.tools.javac.Main";
   34   
   35       /** This is a singleton -- can't create instances!! */
   36       private CompilerAdapterFactory() {
   37       }
   38   
   39       /**
   40        * Based on the parameter passed in, this method creates the necessary
   41        * factory desired.
   42        *
   43        * The current mapping for compiler names are as follows:
   44        * <ul><li>jikes = jikes compiler
   45        * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
   46        * 1.1/1.2
   47        * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+
   48        * <li>jvc, microsoft = the command line compiler from Microsoft's SDK
   49        * for Java / Visual J++
   50        * <li>kjc = the kopi compiler</li>
   51        * <li>gcj = the gcj compiler from gcc</li>
   52        * <li>sj, symantec = the Symantec Java compiler</li>
   53        * <li><i>a fully qualified classname</i> = the name of a compiler
   54        * adapter
   55        * </ul>
   56        *
   57        * @param compilerType either the name of the desired compiler, or the
   58        * full classname of the compiler's adapter.
   59        * @param task a task to log through.
   60        * @return the compiler adapter
   61        * @throws BuildException if the compiler type could not be resolved into
   62        * a compiler adapter.
   63        */
   64       public static CompilerAdapter getCompiler(String compilerType, Task task)
   65           throws BuildException {
   66               boolean isClassicCompilerSupported = true;
   67               //as new versions of java come out, add them to this test
   68               if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)
   69                   && !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3)) {
   70                   isClassicCompilerSupported = false;
   71               }
   72   
   73               if (compilerType.equalsIgnoreCase("jikes")) {
   74                   return new Jikes();
   75               }
   76               if (compilerType.equalsIgnoreCase("extJavac")) {
   77                   return new JavacExternal();
   78               }
   79               if (compilerType.equalsIgnoreCase("classic")
   80                   || compilerType.equalsIgnoreCase("javac1.1")
   81                   || compilerType.equalsIgnoreCase("javac1.2")) {
   82                   if (isClassicCompilerSupported) {
   83                       return new Javac12();
   84                   } else {
   85                       task.log("This version of java does "
   86                                                + "not support the classic "
   87                                                + "compiler; upgrading to modern",
   88                                                Project.MSG_WARN);
   89                       compilerType = "modern";
   90                   }
   91               }
   92               //on java<=1.3 the modern falls back to classic if it is not found
   93               //but on java>=1.4 we just bail out early
   94               if (compilerType.equalsIgnoreCase("modern")
   95                   || compilerType.equalsIgnoreCase("javac1.3")
   96                   || compilerType.equalsIgnoreCase("javac1.4")
   97                   || compilerType.equalsIgnoreCase("javac1.5")
   98                   || compilerType.equalsIgnoreCase("javac1.6")) {
   99                   // does the modern compiler exist?
  100                   if (doesModernCompilerExist()) {
  101                       return new Javac13();
  102                   } else {
  103                       if (isClassicCompilerSupported) {
  104                           task.log("Modern compiler not found - looking for "
  105                                    + "classic compiler", Project.MSG_WARN);
  106                           return new Javac12();
  107                       } else {
  108                           throw new BuildException("Unable to find a javac "
  109                                                    + "compiler;\n"
  110                                                    + MODERN_COMPILER
  111                                                    + " is not on the "
  112                                                    + "classpath.\n"
  113                                                    + "Perhaps JAVA_HOME does not"
  114                                                    + " point to the JDK.\n"
  115                                   + "It is currently set to \""
  116                                   + JavaEnvUtils.getJavaHome()
  117                                   + "\"");
  118                       }
  119                   }
  120               }
  121   
  122               if (compilerType.equalsIgnoreCase("jvc")
  123                   || compilerType.equalsIgnoreCase("microsoft")) {
  124                   return new Jvc();
  125               }
  126               if (compilerType.equalsIgnoreCase("kjc")) {
  127                   return new Kjc();
  128               }
  129               if (compilerType.equalsIgnoreCase("gcj")) {
  130                   return new Gcj();
  131               }
  132               if (compilerType.equalsIgnoreCase("sj")
  133                   || compilerType.equalsIgnoreCase("symantec")) {
  134                   return new Sj();
  135               }
  136               return resolveClassName(compilerType);
  137           }
  138   
  139       /**
  140        * query for the Modern compiler existing
  141        * @return true if classic os on the classpath
  142        */
  143       private static boolean doesModernCompilerExist() {
  144           try {
  145               Class.forName(MODERN_COMPILER);
  146               return true;
  147           } catch (ClassNotFoundException cnfe) {
  148               try {
  149                   ClassLoader cl = CompilerAdapterFactory.class.getClassLoader();
  150                   if (cl != null) {
  151                       cl.loadClass(MODERN_COMPILER);
  152                       return true;
  153                   }
  154               } catch (ClassNotFoundException cnfe2) {
  155                   // Ignore Exception
  156               }
  157           }
  158           return false;
  159       }
  160   
  161       /**
  162        * Tries to resolve the given classname into a compiler adapter.
  163        * Throws a fit if it can't.
  164        *
  165        * @param className The fully qualified classname to be created.
  166        * @throws BuildException This is the fit that is thrown if className
  167        * isn't an instance of CompilerAdapter.
  168        */
  169       private static CompilerAdapter resolveClassName(String className)
  170           throws BuildException {
  171           return (CompilerAdapter) ClasspathUtils.newInstance(className,
  172                   CompilerAdapterFactory.class.getClassLoader(),
  173                   CompilerAdapter.class);
  174       }
  175   
  176   }

Save This Page
Home » apache-ant-1.7.1-src » org.apache.tools » ant » taskdefs » compilers » [javadoc | source]