View Javadoc
1   package org.codehaus.mojo.jaxb2.shared.environment;
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.logging.Log;
23  import org.codehaus.mojo.jaxb2.shared.Validate;
24  import org.codehaus.mojo.jaxb2.shared.environment.classloading.ThreadContextClassLoaderBuilder;
25  import org.codehaus.mojo.jaxb2.shared.environment.classloading.ThreadContextClassLoaderHolder;
26  import org.codehaus.mojo.jaxb2.shared.environment.logging.LoggingHandlerEnvironmentFacet;
27  
28  import java.util.ArrayList;
29  import java.util.List;
30  
31  /**
32   * Compound EnvironmentFacet implementation which is used to set up and use a collection
33   * of other EnvironmentFacet instances during the run of the JAXB2 Maven Plugin.
34   *
35   * @author <a href="mailto:lj@jguru.se">Lennart J&ouml;relid</a>, jGuru Europe AB
36   */
37  public class ToolExecutionEnvironment extends AbstractLogAwareFacet {
38  
39      // Internal state
40      private ThreadContextClassLoaderBuilder builder;
41      private ThreadContextClassLoaderHolder holder;
42      private LoggingHandlerEnvironmentFacet loggingHandlerEnvironmentFacet;
43      private List<EnvironmentFacet> extraFacets;
44  
45      /**
46       * Creates a new ToolExecutionEnvironment object wrapping the supplied Maven Log.
47       *
48       * @param mavenLog            The active Maven Log.
49       * @param builder             The ThreadContextClassLoaderBuilder used to set up a ThreadContext ClassLoader for
50       *                            this tool execution environment.
51       * @param loggingHandlerFacet The EnvironmentFacet for replacing Handlers from Java Util Logging with a Maven Log.
52       */
53      public ToolExecutionEnvironment(final Log mavenLog,
54                                      final ThreadContextClassLoaderBuilder builder,
55                                      final LoggingHandlerEnvironmentFacet loggingHandlerFacet) {
56          super(mavenLog);
57  
58          // Check sanity
59          Validate.notNull(builder, "builder");
60          Validate.notNull(loggingHandlerFacet, "loggingHandlerFacet");
61  
62          // Assign internal state
63          this.builder = builder;
64          this.loggingHandlerEnvironmentFacet = loggingHandlerFacet;
65          extraFacets = new ArrayList<EnvironmentFacet>();
66      }
67  
68      /**
69       * Adds the supplied EnvironmentFacet to this ToolExecutionEnvironment.
70       *
71       * @param facet the non-null EnvironmentFacet to add to this ToolExecutionEnvironment.
72       */
73      public void add(final EnvironmentFacet facet) {
74  
75          // Check sanity
76          Validate.notNull(facet, "facet");
77  
78          // All done.
79          extraFacets.add(facet);
80      }
81  
82      /**
83       * Delegate method retrieving the classpath as argument from the underlying ThreadContextClassLoaderHolder.
84       * Note that the setup method must be invoked before this one is.
85       *
86       * @return the ClassPath as an argument to external processes such as XJC.
87       * @see ThreadContextClassLoaderHolder#getClassPathAsArgument()
88       */
89      public String getClassPathAsArgument() {
90  
91          // Check sanity
92          if (holder == null) {
93              throw new IllegalStateException("Cannot retrieve the classpath argument before calling 'setup'");
94          }
95  
96          // Delegate and return
97          return holder.getClassPathAsArgument();
98      }
99  
100     /**
101      * {@inheritDoc}
102      */
103     @Override
104     public final void setup() {
105 
106         // Setup mandatory environment facets
107         try {
108 
109             if (log.isDebugEnabled()) {
110                 log.debug("ToolExecutionEnvironment setup -- Starting.");
111             }
112 
113             // Build the ClassLoader as required for the JAXB tools
114             holder = builder.buildAndSet();
115 
116             // Redirect the JUL logging handler used by the tools to the Maven log.
117             loggingHandlerEnvironmentFacet.setup();
118 
119             // Setup optional/extra environment facets
120             for (EnvironmentFacet current : extraFacets) {
121                 try {
122                     current.setup();
123                 } catch (Exception e) {
124                     throw new IllegalStateException("Could not setup() EnvironmentFacet of type ["
125                             + current.getClass().getName() + "]", e);
126                 }
127             }
128 
129             if (log.isDebugEnabled()) {
130                 log.debug("ToolExecutionEnvironment setup -- Done.");
131             }
132 
133         } catch (IllegalStateException e) {
134             throw e;
135         } catch (Exception e) {
136             throw new IllegalStateException("Could not setup() mandatory EnvironmentFacets.", e);
137         }
138     }
139 
140     /**
141      * {@inheritDoc}
142      */
143     @Override
144     public final void restore() {
145 
146         try {
147 
148             if (log.isDebugEnabled()) {
149                 log.debug("ToolExecutionEnvironment restore -- Starting.");
150             }
151 
152             for (EnvironmentFacet current : extraFacets) {
153                 try {
154                     current.restore();
155                 } catch (Exception e) {
156                     throw new IllegalStateException("Could not restore() EnvironmentFacet of type ["
157                             + current.getClass().getName() + "]", e);
158                 }
159             }
160         } finally {
161 
162             // Restore the logging handler structure.
163             loggingHandlerEnvironmentFacet.restore();
164 
165             // Restore the original ClassLoader
166             holder.restoreClassLoaderAndReleaseThread();
167 
168             if (log.isDebugEnabled()) {
169                 log.debug("ToolExecutionEnvironment restore -- Done.");
170             }
171         }
172     }
173 }