File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\maven-plugin\src\main\java\hudson\maven\ExecutedMojo.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.maven;
25
26 import static hudson.Util.intern;
27 import hudson.Util;
28 import jenkins.model.Jenkins;
29 import hudson.remoting.Which;
30 import hudson.util.ReflectionUtils;
31
32 import java.io.File;
33 import java.io.FileInputStream;
34 import java.io.IOException;
35 import java.io.Serializable;
36 import java.lang.reflect.Method;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41
42 import org.apache.maven.plugin.descriptor.MojoDescriptor;
43 import org.apache.maven.plugin.descriptor.PluginDescriptor;
44 import org.codehaus.plexus.classworlds.realm.ClassRealm;
45 import org.kohsuke.stapler.Stapler;
46
47 /**
48 * Persisted record of mojo execution.
49 *
50 * <p>
51 * This information is first recorded in the maven process, then sent over
52 * the remoting layer to the master, then persisted via XStream.
53 *
54 * @author Kohsuke Kawaguchi
55 */
56 public final class ExecutedMojo implements Serializable {
57 private static final long serialVersionUID = -3048316415397586490L;
58 /**
59 * Plugin group ID.
60 */
61 public final String groupId;
62 /**
63 * Plugin artifact ID.
64 */
65 public final String artifactId;
66 /**
67 * Plugin version.
68 */
69 public final String version;
70 /**
71 * Mojo name.
72 */
73 public final String goal;
74 /**
75 * Optional execution ID, when the same mojo gets executed multiple times.
76 */
77 public final String executionId;
78 /**
79 * How long did it take to execute this goal? in milli-seconds.
80 * (precision might not be 1ms)
81 */
82 public final long duration;
83 /**
84 * MD5 hash of the plugin jar.
85 */
86 public final String digest;
87
88 public ExecutedMojo(MojoInfo mojo, long duration) {
89 this.groupId = mojo.pluginName.groupId;
90 this.artifactId = mojo.pluginName.artifactId;
91 this.version = mojo.pluginName.version;
92 this.goal = mojo.getGoal();
93 this.executionId = mojo.mojoExecution.getExecutionId();
94 this.duration = duration;
95
96 String digest = null;
97 MojoDescriptor md = mojo.mojoExecution.getMojoDescriptor();
98 PluginDescriptor pd = md.getPluginDescriptor();
99 try {
100 Class<?> clazz = getMojoClass( md, pd );
101 if (clazz!=null) {
102 File jarFile = Which.jarFile(clazz);
103 if (jarFile.isFile()) {
104 digest = Util.getDigestOf(new FileInputStream(jarFile));
105 } else {
106 // Maybe mojo was loaded from a classes dir instead of from a jar (JENKINS-5044)
107 LOGGER.log(Level.WARNING, "Cannot calculate digest of mojo class, because mojo wasn't loaded from a jar, but from: "
108 + jarFile);
109 }
110 } else {
111 LOGGER.log(Level.WARNING, "Failed to getClass for "+md.getImplementation());
112 }
113
114 } catch (IllegalArgumentException e) {
115 LOGGER.log(Level.WARNING, "Failed to locate jar for "+md.getImplementation(),e);
116 } catch (ClassNotFoundException e) {
117 // perhaps the plugin has failed to load.
118 } catch (IOException e) {
119 LOGGER.log(Level.WARNING, "Failed to calculate digest for "+md.getImplementation(),e);
120 }
121 this.digest = digest;
122 }
123
124 private Class<?> getMojoClass(MojoDescriptor md, PluginDescriptor pd) throws ClassNotFoundException {
125 try {
126 ClassRealm classRealm = pd.getClassRealm();
127 return classRealm == null ? null : classRealm.loadClass( md.getImplementation() );
128 } catch (NoSuchMethodError e) {
129 // maybe we are in maven2 build ClassRealm package has changed
130 return getMojoClassForMaven2( md, pd );
131 }
132 }
133
134 private Class<?> getMojoClassForMaven2(MojoDescriptor md, PluginDescriptor pd) throws ClassNotFoundException {
135
136 Method method = ReflectionUtils.getPublicMethodNamed( pd.getClass(), "getClassRealm" );
137
138 org.codehaus.classworlds.ClassRealm cl =
139 (org.codehaus.classworlds.ClassRealm) ReflectionUtils.invokeMethod( method, pd );
140
141 if (cl==null)
142 {
143 return null;
144 }
145 Class<?> clazz = cl.loadClass( md.getImplementation() );
146 return clazz;
147
148 }
149
150
151 /**
152 * Copy constructor used for interning.
153 */
154 private ExecutedMojo(String groupId, String artifactId, String version, String goal, String executionId, long duration, String digest) {
155 this.groupId = groupId;
156 this.artifactId = artifactId;
157 this.version = version;
158 this.goal = goal;
159 this.executionId = executionId;
160 this.duration = duration;
161 this.digest = digest;
162 }
163
164 /**
165 * Lots of {@link ExecutedMojo}s tend to have the same groupId, artifactId, etc., so interning them help
166 * with memory consumption.
167 *
168 * TODO: better if XStream has a declarative way of marking fields as "target for intern".
169 */
170 protected Object readResolve() {
171 return new ExecutedMojo(intern(groupId),intern(artifactId),intern(version),intern(goal),intern(executionId),duration,intern(digest));
172 }
173
174 /**
175 * Returns duration in a human readable text.
176 */
177 public String getDurationString() {
178 return Util.getTimeSpanString(duration);
179 }
180
181 public String getReadableExecutionId() {
182 if(executionId==null) return "-";
183 else return executionId;
184 }
185
186 /**
187 * Returns a hyperlink for the plugin name if there's one.
188 * Otherwise null.
189 */
190 public String getPluginLink(Cache c) {
191 MavenModule m = c.get(this);
192 if(m!=null)
193 return Stapler.getCurrentRequest().getContextPath()+m.getUrl();
194 if(groupId.equals("org.apache.maven.plugins"))
195 return "http://maven.apache.org/plugins/"+artifactId+'/';
196 if (groupId.equals("org.codehaus.mojo"))
197 return "http://mojo.codehaus.org/"+artifactId+'/';
198 return null;
199 }
200
201 public String getGoalLink(Cache c) {
202 if(groupId.equals("org.apache.maven.plugins"))
203 return "http://maven.apache.org/plugins/"+artifactId+'/'+goal+"-mojo.html";
204 if (groupId.equals("org.codehaus.mojo"))
205 return "http://mojo.codehaus.org/"+artifactId+'/'+goal+"-mojo.html";
206 return null;
207 }
208
209 /**
210 * Used during the HTML rendering to cache the index.
211 */
212 public static final class Cache {
213 /**
214 * All maven modules in this Hudson by their names.
215 */
216 public final Map<ModuleName,MavenModule> modules = new HashMap<ModuleName,MavenModule>();
217
218 public Cache() {
219 for( MavenModule m : Jenkins.getInstance().getAllItems(MavenModule.class))
220 modules.put(m.getModuleName(),m);
221 }
222
223 public MavenModule get(ExecutedMojo mojo) {
224 return modules.get(new ModuleName(mojo.groupId,mojo.artifactId));
225 }
226 }
227
228 private static final Logger LOGGER = Logger.getLogger(ExecutedMojo.class.getName());
229 }
230