Save This Page
Home » apache-ant-1.8.1 » 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.types.Path;
   25   import org.apache.tools.ant.util.ClasspathUtils;
   26   import org.apache.tools.ant.util.JavaEnvUtils;
   27   
   28   /**
   29    * Creates the necessary compiler adapter, given basic criteria.
   30    *
   31    * @since Ant 1.3
   32    */
   33   public final class CompilerAdapterFactory {
   34       private static final String MODERN_COMPILER = "com.sun.tools.javac.Main";
   35   
   36       /** This is a singleton -- can't create instances!! */
   37       private CompilerAdapterFactory() {
   38       }
   39   
   40       /**
   41        * Based on the parameter passed in, this method creates the necessary
   42        * factory desired.
   43        *
   44        * The current mapping for compiler names are as follows:
   45        * <ul><li>jikes = jikes compiler
   46        * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
   47        * 1.1/1.2
   48        * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+
   49        * <li>jvc, microsoft = the command line compiler from Microsoft's SDK
   50        * for Java / Visual J++
   51        * <li>kjc = the kopi compiler</li>
   52        * <li>gcj = the gcj compiler from gcc</li>
   53        * <li>sj, symantec = the Symantec Java compiler</li>
   54        * <li><i>a fully qualified classname</i> = the name of a compiler
   55        * adapter
   56        * </ul>
   57        *
   58        * @param compilerType either the name of the desired compiler, or the
   59        * full classname of the compiler's adapter.
   60        * @param task a task to log through.
   61        * @return the compiler adapter
   62        * @throws BuildException if the compiler type could not be resolved into
   63        * a compiler adapter.
   64        */
   65       public static CompilerAdapter getCompiler(String compilerType, Task task)
   66           throws BuildException {
   67           return getCompiler(compilerType, task, null);
   68       }
   69   
   70       /**
   71        * Based on the parameter passed in, this method creates the necessary
   72        * factory desired.
   73        *
   74        * The current mapping for compiler names are as follows:
   75        * <ul><li>jikes = jikes compiler
   76        * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
   77        * 1.1/1.2
   78        * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+
   79        * <li>jvc, microsoft = the command line compiler from Microsoft's SDK
   80        * for Java / Visual J++
   81        * <li>kjc = the kopi compiler</li>
   82        * <li>gcj = the gcj compiler from gcc</li>
   83        * <li>sj, symantec = the Symantec Java compiler</li>
   84        * <li><i>a fully qualified classname</i> = the name of a compiler
   85        * adapter
   86        * </ul>
   87        *
   88        * @param compilerType either the name of the desired compiler, or the
   89        * full classname of the compiler's adapter.
   90        * @param task a task to log through.
   91        * @param classpath the classpath to use when looking up an
   92        * adapter class
   93        * @return the compiler adapter
   94        * @throws BuildException if the compiler type could not be resolved into
   95        * a compiler adapter.
   96        * @since Ant 1.8.0
   97        */
   98       public static CompilerAdapter getCompiler(String compilerType, Task task,
   99                                                 Path classpath)
  100           throws BuildException {
  101               if (compilerType.equalsIgnoreCase("jikes")) {
  102                   return new Jikes();
  103               }
  104               if (compilerType.equalsIgnoreCase("extjavac")) {
  105                   return new JavacExternal();
  106               }
  107               if (compilerType.equalsIgnoreCase("classic")
  108                   || compilerType.equalsIgnoreCase("javac1.1")
  109                   || compilerType.equalsIgnoreCase("javac1.2")) {
  110                   task.log("This version of java does "
  111                                            + "not support the classic "
  112                                            + "compiler; upgrading to modern",
  113                                            Project.MSG_WARN);
  114                   compilerType = "modern";
  115               }
  116               //on java<=1.3 the modern falls back to classic if it is not found
  117               //but on java>=1.4 we just bail out early
  118               if (compilerType.equalsIgnoreCase("modern")
  119                   || compilerType.equalsIgnoreCase("javac1.3")
  120                   || compilerType.equalsIgnoreCase("javac1.4")
  121                   || compilerType.equalsIgnoreCase("javac1.5")
  122                   || compilerType.equalsIgnoreCase("javac1.6")) {
  123                   // does the modern compiler exist?
  124                   if (doesModernCompilerExist()) {
  125                       return new Javac13();
  126                   } else {
  127                       throw new BuildException("Unable to find a javac "
  128                                                + "compiler;\n"
  129                                                + MODERN_COMPILER
  130                                                + " is not on the "
  131                                                + "classpath.\n"
  132                                                + "Perhaps JAVA_HOME does not"
  133                                                + " point to the JDK.\n"
  134                               + "It is currently set to \""
  135                               + JavaEnvUtils.getJavaHome()
  136                               + "\"");
  137                   }
  138               }
  139   
  140               if (compilerType.equalsIgnoreCase("jvc")
  141                   || compilerType.equalsIgnoreCase("microsoft")) {
  142                   return new Jvc();
  143               }
  144               if (compilerType.equalsIgnoreCase("kjc")) {
  145                   return new Kjc();
  146               }
  147               if (compilerType.equalsIgnoreCase("gcj")) {
  148                   return new Gcj();
  149               }
  150               if (compilerType.equalsIgnoreCase("sj")
  151                   || compilerType.equalsIgnoreCase("symantec")) {
  152                   return new Sj();
  153               }
  154               return resolveClassName(compilerType,
  155                                       // Memory-Leak in line below
  156                                   task.getProject().createClassLoader(classpath));
  157           }
  158   
  159       /**
  160        * query for the Modern compiler existing
  161        * @return true if classic os on the classpath
  162        */
  163       private static boolean doesModernCompilerExist() {
  164           try {
  165               Class.forName(MODERN_COMPILER);
  166               return true;
  167           } catch (ClassNotFoundException cnfe) {
  168               try {
  169                   ClassLoader cl = CompilerAdapterFactory.class.getClassLoader();
  170                   if (cl != null) {
  171                       cl.loadClass(MODERN_COMPILER);
  172                       return true;
  173                   }
  174               } catch (ClassNotFoundException cnfe2) {
  175                   // Ignore Exception
  176               }
  177           }
  178           return false;
  179       }
  180   
  181       /**
  182        * Tries to resolve the given classname into a compiler adapter.
  183        * Throws a fit if it can't.
  184        *
  185        * @param className The fully qualified classname to be created.
  186        * @param loader the classloader to use
  187        * @throws BuildException This is the fit that is thrown if className
  188        * isn't an instance of CompilerAdapter.
  189        */
  190       private static CompilerAdapter resolveClassName(String className,
  191                                                       ClassLoader loader)
  192           throws BuildException {
  193           return (CompilerAdapter) ClasspathUtils.newInstance(className,
  194                   loader != null ? loader :
  195                   CompilerAdapterFactory.class.getClassLoader(),
  196                   CompilerAdapter.class);
  197       }
  198   
  199   }

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