View Javadoc
1   package org.apache.maven.plugin.coreit;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.AbstractMojo;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugin.MojoFailureException;
25  
26  import java.io.File;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Properties;
31  
32  /**
33   * Checks whether objects obtained from the Maven core are assignment-compatible with types loaded from the plugin class
34   * loader. In other words, checks that types shared with the core realm are imported into the plugin realm.
35   *
36   * @author Benjamin Bentmann
37   *
38   * @goal instanceof
39   * @phase initialize
40   */
41  public class InstanceofMojo
42      extends AbstractMojo
43  {
44  
45      /**
46       * The path to the properties file used to track the results of the instanceof tests.
47       *
48       * @parameter property="clsldr.instanceofPropertiesFile"
49       */
50      private File instanceofPropertiesFile;
51  
52      /**
53       * The qualified name of the type to which the objects should be assignment-compatible. This type will be loaded
54       * from the plugin class loader, just like as if it was imported in the plugin source code.
55       *
56       * @parameter property="clsldr.className"
57       */
58      private String className;
59  
60      /**
61       * A list of expressions that denote the object instances that should be type-checked.
62       *
63       * @parameter
64       */
65      private String[] objectExpressions;
66  
67      /**
68       * A list of injected component instances that should be type-checked.
69       *
70       * @component role="org.apache.maven.plugin.coreit.Component"
71       */
72      private List components;
73  
74      /**
75       * The current Maven project against which expressions are evaluated.
76       *
77       * @parameter default-value="${project}"
78       * @readonly
79       */
80      private Object project;
81  
82      /**
83       * Runs this mojo.
84       *
85       * @throws MojoExecutionException If the output file could not be created.
86       */
87      public void execute()
88          throws MojoExecutionException, MojoFailureException
89      {
90          Class type;
91          try
92          {
93              getLog().info( "[MAVEN-CORE-IT-LOG] Loading class " + className );
94              type = getClass().getClassLoader().loadClass( className );
95              getLog().info( "[MAVEN-CORE-IT-LOG] Loaded class from " + type.getClassLoader() );
96          }
97          catch ( ClassNotFoundException e )
98          {
99              throw new MojoExecutionException( "Failed to load type " + className, e );
100         }
101 
102         Properties instanceofProperties = new Properties();
103 
104         if ( objectExpressions != null && objectExpressions.length > 0 )
105         {
106             Map contexts = new HashMap();
107             contexts.put( "project", project );
108             contexts.put( "pom", project );
109 
110             for ( String expression : objectExpressions )
111             {
112                 getLog().info( "[MAVEN-CORE-IT-LOG] Evaluating expression " + expression );
113                 Object object = ExpressionUtil.evaluate( expression, contexts );
114                 getLog().info( "[MAVEN-CORE-IT-LOG] Checking object " + object );
115                 if ( object != null )
116                 {
117                     getLog().info( "[MAVEN-CORE-IT-LOG]   Loaded class " + object.getClass().getName() );
118                     getLog().info( "[MAVEN-CORE-IT-LOG]   Loaded class from " + object.getClass().getClassLoader() );
119                 }
120                 instanceofProperties.setProperty( expression.replace( '/', '.' ),
121                                                   Boolean.toString( type.isInstance( object ) ) );
122             }
123         }
124 
125         if ( components != null && !components.isEmpty() )
126         {
127             for ( Object object : components )
128             {
129                 getLog().info( "[MAVEN-CORE-IT-LOG] Checking component " + object );
130                 getLog().info( "[MAVEN-CORE-IT-LOG]   Loaded class " + object.getClass().getName() );
131                 getLog().info( "[MAVEN-CORE-IT-LOG]   Loaded class from " + object.getClass().getClassLoader() );
132                 instanceofProperties.setProperty( object.getClass().getName(),
133                                                   Boolean.toString( type.isInstance( object ) ) );
134             }
135         }
136 
137         getLog().info( "[MAVEN-CORE-IT-LOG] Creating output file " + instanceofPropertiesFile );
138 
139         PropertiesUtil.write( instanceofPropertiesFile, instanceofProperties );
140 
141         getLog().info( "[MAVEN-CORE-IT-LOG] Created output file " + instanceofPropertiesFile );
142     }
143 
144 }