Coverage Report - org.codehaus.plexus.compiler.javac.JavaxToolsCompiler
 
Classes in this File Line Coverage Branch Coverage Complexity
JavaxToolsCompiler
76%
55/72
63%
24/38
8,5
JavaxToolsCompiler$1
100%
2/2
N/A
8,5
 
 1  
 package org.codehaus.plexus.compiler.javac;
 2  
 /*
 3  
  * Licensed to the Apache Software Foundation (ASF) under one
 4  
  * or more contributor license agreements.  See the NOTICE file
 5  
  * distributed with this work for additional information
 6  
  * regarding copyright ownership.  The ASF licenses this file
 7  
  * to you under the Apache License, Version 2.0 (the
 8  
  * "License"); you may not use this file except in compliance
 9  
  * with the License.  You may obtain a copy of the License at
 10  
  *
 11  
  *   http://www.apache.org/licenses/LICENSE-2.0
 12  
  *
 13  
  * Unless required by applicable law or agreed to in writing,
 14  
  * software distributed under the License is distributed on an
 15  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 16  
  * KIND, either express or implied.  See the License for the
 17  
  * specific language governing permissions and limitations
 18  
  * under the License.
 19  
  */
 20  
 
 21  
 import org.codehaus.plexus.compiler.CompilerConfiguration;
 22  
 import org.codehaus.plexus.compiler.CompilerMessage;
 23  
 import org.codehaus.plexus.compiler.CompilerException;
 24  
 import org.codehaus.plexus.compiler.CompilerResult;
 25  
 
 26  
 import javax.tools.Diagnostic;
 27  
 import javax.tools.DiagnosticCollector;
 28  
 import javax.tools.JavaCompiler;
 29  
 import javax.tools.JavaFileObject;
 30  
 import javax.tools.StandardJavaFileManager;
 31  
 import javax.tools.ToolProvider;
 32  
 import java.nio.charset.Charset;
 33  
 import java.util.ArrayList;
 34  
 import java.util.Arrays;
 35  
 import java.util.Collections;
 36  
 import java.util.List;
 37  
 import java.util.concurrent.CopyOnWriteArrayList;
 38  
 
 39  
 /**
 40  
  * @author Olivier Lamy
 41  
  * @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
 42  
  * @since 2.0
 43  
  */
 44  0
 public class JavaxToolsCompiler
 45  
 {
 46  
     /**
 47  
      * is that thread safe ???
 48  
      */
 49  
     @SuppressWarnings( "restriction" )
 50  1
     static final JavaCompiler COMPILER = ToolProvider.getSystemJavaCompiler();
 51  
 
 52  1
     private static List<JavaCompiler> JAVA_COMPILERS = new CopyOnWriteArrayList<>();
 53  
 
 54  
     protected static JavaCompiler getJavaCompiler( CompilerConfiguration compilerConfiguration )
 55  
     {
 56  7
         switch ( compilerConfiguration.getCompilerReuseStrategy() )
 57  
         {
 58  
             case AlwaysNew:
 59  0
                 return ToolProvider.getSystemJavaCompiler();
 60  
             case ReuseCreated:
 61  
                 JavaCompiler javaCompiler;
 62  7
                 synchronized ( JAVA_COMPILERS )
 63  
                 {
 64  7
                     if ( JAVA_COMPILERS.size() > 0 )
 65  
                     {
 66  6
                         javaCompiler = JAVA_COMPILERS.get( 0 );
 67  6
                         JAVA_COMPILERS.remove( javaCompiler );
 68  6
                         return javaCompiler;
 69  
                     }
 70  1
                 }
 71  1
                 javaCompiler = ToolProvider.getSystemJavaCompiler();
 72  1
                 return javaCompiler;
 73  
             case ReuseSame:
 74  
             default:
 75  0
                 return COMPILER;
 76  
         }
 77  
 
 78  
     }
 79  
 
 80  
     static void releaseJavaCompiler( JavaCompiler javaCompiler, CompilerConfiguration compilerConfiguration )
 81  
     {
 82  7
         if ( javaCompiler == null )
 83  
         {
 84  0
             return;
 85  
         }
 86  7
         if ( compilerConfiguration.getCompilerReuseStrategy()
 87  
             == CompilerConfiguration.CompilerReuseStrategy.ReuseCreated )
 88  
         {
 89  7
             JAVA_COMPILERS.add( javaCompiler );
 90  
         }
 91  7
     }
 92  
 
 93  
     static CompilerResult compileInProcess( String[] args, final CompilerConfiguration config, String[] sourceFiles )
 94  
         throws CompilerException
 95  
     {
 96  7
         JavaCompiler compiler = getJavaCompiler( config );
 97  
         try
 98  
         {
 99  7
             if ( compiler == null )
 100  
             {
 101  0
                 CompilerMessage message = new CompilerMessage( "No compiler is provided in this environment. "
 102  
                                                                    + "Perhaps you are running on a JRE rather than a JDK?",
 103  
                                                                CompilerMessage.Kind.ERROR );
 104  0
                 return new CompilerResult( false, Collections.singletonList( message ) );
 105  
             }
 106  7
             final String sourceEncoding = config.getSourceEncoding();
 107  7
             final Charset sourceCharset = sourceEncoding == null ? null : Charset.forName( sourceEncoding );
 108  7
             final DiagnosticCollector<JavaFileObject> collector = new DiagnosticCollector<JavaFileObject>();
 109  7
             final StandardJavaFileManager standardFileManager =
 110  7
                 compiler.getStandardFileManager( collector, null, sourceCharset );
 111  
 
 112  7
             final Iterable<? extends JavaFileObject> fileObjects =
 113  7
                 standardFileManager.getJavaFileObjectsFromStrings( Arrays.asList( sourceFiles ) );
 114  
 
 115  
              /*(Writer out,
 116  
              JavaFileManager fileManager,
 117  
              DiagnosticListener<? super JavaFileObject> diagnosticListener,
 118  
              Iterable<String> options,
 119  
              Iterable<String> classes,
 120  
              Iterable<? extends JavaFileObject> compilationUnits)*/
 121  
 
 122  7
             List<String> arguments = Arrays.asList( args );
 123  
 
 124  7
             final JavaCompiler.CompilationTask task =
 125  7
                 compiler.getTask( null, standardFileManager, collector, arguments, null, fileObjects );
 126  7
             final Boolean result = task.call();
 127  7
             final ArrayList<CompilerMessage> compilerMsgs = new ArrayList<CompilerMessage>();
 128  7
             for ( Diagnostic<? extends JavaFileObject> diagnostic : collector.getDiagnostics() )
 129  
             {
 130  34
                 CompilerMessage.Kind kind = convertKind(diagnostic);
 131  34
                 String baseMessage = diagnostic.getMessage( null );
 132  34
                 if ( baseMessage == null )
 133  
                 {
 134  0
                     continue;
 135  
                 }
 136  34
                 JavaFileObject source = diagnostic.getSource();
 137  34
                 String longFileName = source == null ? null : source.toUri().getPath();
 138  34
                 String shortFileName = source == null ? null : source.getName();
 139  34
                 String formattedMessage = baseMessage;
 140  34
                 int lineNumber = Math.max( 0, (int) diagnostic.getLineNumber() );
 141  34
                 int columnNumber = Math.max( 0, (int) diagnostic.getColumnNumber() );
 142  34
                 if ( source != null && lineNumber > 0 )
 143  
                 {
 144  
                     // Some compilers like to copy the file name into the message, which makes it appear twice.
 145  6
                     String possibleTrimming = longFileName + ":" + lineNumber + ": ";
 146  6
                     if ( formattedMessage.startsWith( possibleTrimming ) )
 147  
                     {
 148  0
                         formattedMessage = formattedMessage.substring( possibleTrimming.length() );
 149  
                     }
 150  
                     else
 151  
                     {
 152  6
                         possibleTrimming = shortFileName + ":" + lineNumber + ": ";
 153  6
                         if ( formattedMessage.startsWith( possibleTrimming ) )
 154  
                         {
 155  0
                             formattedMessage = formattedMessage.substring( possibleTrimming.length() );
 156  
                         }
 157  
                     }
 158  
                 }
 159  34
                 compilerMsgs.add(
 160  
                     new CompilerMessage( longFileName, kind, lineNumber, columnNumber, lineNumber, columnNumber,
 161  
                                          formattedMessage ) );
 162  34
             }
 163  7
             if ( result != Boolean.TRUE && compilerMsgs.isEmpty() )
 164  
             {
 165  0
                 compilerMsgs.add(
 166  
                     new CompilerMessage( "An unknown compilation problem occurred", CompilerMessage.Kind.ERROR ) );
 167  
             }
 168  
 
 169  14
             return new CompilerResult( result, compilerMsgs );
 170  
         }
 171  0
         catch ( Exception e )
 172  
         {
 173  0
             throw new CompilerException( e.getMessage(), e );
 174  
         }
 175  
         finally
 176  
         {
 177  7
             releaseJavaCompiler( compiler, config );
 178  
 
 179  
         }
 180  
     }
 181  
 
 182  
     public static CompilerMessage.Kind convertKind(Diagnostic<? extends JavaFileObject> diagnostic) {
 183  
         CompilerMessage.Kind kind;
 184  34
         switch ( diagnostic.getKind() )
 185  
         {
 186  
             case ERROR:
 187  4
                 kind = CompilerMessage.Kind.ERROR;
 188  4
                 break;
 189  
             case WARNING:
 190  30
                 kind = CompilerMessage.Kind.WARNING;
 191  30
                 break;
 192  
             case MANDATORY_WARNING:
 193  0
                 kind = CompilerMessage.Kind.MANDATORY_WARNING;
 194  0
                 break;
 195  
             case NOTE:
 196  0
                 kind = CompilerMessage.Kind.NOTE;
 197  0
                 break;
 198  
             default:
 199  0
                 kind = CompilerMessage.Kind.OTHER;
 200  
                 break;
 201  
         }
 202  34
         return kind;
 203  
     }
 204  
 }