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