1   /*
2    * ========================================================================
3    *
4    * Codehaus CARGO, copyright 2004-2010 Vincent Massol.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   *
18   * ========================================================================
19   */
20  package com.atlassian.maven.plugins.amps.util.ant;
21  
22  import java.util.concurrent.atomic.AtomicBoolean;
23  import java.util.concurrent.atomic.AtomicReference;
24  
25  import org.apache.tools.ant.BuildException;
26  import org.apache.tools.ant.taskdefs.Java;
27  
28  /**
29   * Executor that executes an Ant's {@link Java} command in a separate thread.
30   * 
31   * @version $Id$
32   */
33  public class AntJavaExecutorThread extends Thread
34  {
35      /**
36       * The Ant java command to execute.
37       */
38      private Java java;
39      
40      /** Build exception. */
41      private AtomicReference<BuildException> ex = new AtomicReference<BuildException>();
42      
43      /** Finished flag. */
44      private AtomicBoolean finishedFlag = new AtomicBoolean(false);
45  
46      /**
47       * @param java the Ant java command to execute
48       */
49      public AntJavaExecutorThread(Java java)
50      {
51          this.java = java;
52      }
53  
54      /**
55       * Returns a build exception.
56       * @return the build exception
57       */
58      public BuildException getBuildException()
59      {
60          return this.ex.get();
61      }
62  
63      /**
64       * Set the build exception.
65       * @param ex The build exception
66       */
67      private void setBuildException(BuildException ex)
68      {
69          this.ex.set(ex);
70      }
71  
72      /**
73       * Determine if its finished or not
74       * @return If its finished or not
75       */
76      public boolean isFinished()
77      {
78          return finishedFlag.get();
79      }
80  
81      /**
82       * Set if the its finished or not
83       * @param b sets finish state
84       */
85      public void setFinished(boolean b)
86      {
87          finishedFlag.set(b);
88      }
89  
90      /**
91       * Execute the Ant's java command.
92       */
93      @Override
94      public void run()
95      {        
96          // This makes Ant Java task to throw an exception when something goes
97          // wrong.
98          this.java.setFailonerror(true);
99  
100         try
101         {
102             // Blocking call
103             this.java.execute();
104         }
105         catch (BuildException ex)
106         {
107             if (ex.getMessage().contains("Java returned: 1"))
108             {
109                 ex = new BuildException(ex.getMessage()
110                     + "  See log for details.", ex.getCause(), ex.getLocation());
111             }
112             this.setBuildException(ex);
113         }
114         finally
115         {
116             this.setFinished(true);
117         }
118 
119         // Only reach here when the container is stopped
120     }
121 }