Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
WebappStructure |
|
| 2.78125;2,781 | ||||
WebappStructure$DependenciesAnalysisCallback |
|
| 2.78125;2,781 | ||||
WebappStructure$RegistrationCallback |
|
| 2.78125;2,781 |
1 | package org.apache.maven.plugin.war.util; | |
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.artifact.Artifact; | |
23 | import org.apache.maven.model.Dependency; | |
24 | import org.codehaus.plexus.util.StringUtils; | |
25 | ||
26 | import java.io.IOException; | |
27 | import java.util.ArrayList; | |
28 | import java.util.Collections; | |
29 | import java.util.HashMap; | |
30 | import java.util.Iterator; | |
31 | import java.util.List; | |
32 | import java.util.Map; | |
33 | import java.util.Set; | |
34 | ||
35 | /** | |
36 | * Represents the structure of a web application composed of multiple | |
37 | * overlays. Each overlay is registered within this structure with the | |
38 | * set of files it holds. | |
39 | * <p/> | |
40 | * Note that this structure is persisted to disk at each invocation to | |
41 | * store which owner holds which path (file). | |
42 | * | |
43 | * @author Stephane Nicoll | |
44 | * @version $Id: WebappStructure.java 1390192 2012-09-25 22:16:06Z dennisl $ | |
45 | */ | |
46 | public class WebappStructure | |
47 | { | |
48 | ||
49 | private Map registeredFiles; | |
50 | ||
51 | private List dependenciesInfo; | |
52 | ||
53 | 126 | private transient PathSet allFiles = new PathSet(); |
54 | ||
55 | private transient WebappStructure cache; | |
56 | ||
57 | /** | |
58 | * Creates a new empty instance. | |
59 | * | |
60 | * @param dependencies the dependencies of the project | |
61 | */ | |
62 | public WebappStructure( List dependencies ) | |
63 | 61 | { |
64 | 61 | this.dependenciesInfo = createDependenciesInfoList( dependencies ); |
65 | 61 | this.registeredFiles = new HashMap(); |
66 | 61 | this.cache = null; |
67 | ||
68 | 61 | } |
69 | ||
70 | /** | |
71 | * Creates a new instance with the specified cache. | |
72 | * | |
73 | * @param dependencies the dependencies of the project | |
74 | * @param cache the cache | |
75 | */ | |
76 | public WebappStructure( List dependencies, WebappStructure cache ) | |
77 | 65 | { |
78 | 65 | this.dependenciesInfo = createDependenciesInfoList( dependencies ); |
79 | 65 | this.registeredFiles = new HashMap(); |
80 | 65 | if ( cache == null ) |
81 | { | |
82 | 54 | this.cache = new WebappStructure( dependencies ); |
83 | ||
84 | } | |
85 | else | |
86 | { | |
87 | 11 | this.cache = cache; |
88 | } | |
89 | 65 | } |
90 | ||
91 | /** | |
92 | * Returns the list of {@link DependencyInfo} for the project. | |
93 | * | |
94 | * @return the dependencies information of the project | |
95 | */ | |
96 | public List getDependenciesInfo() | |
97 | { | |
98 | 3 | return dependenciesInfo; |
99 | } | |
100 | ||
101 | /** | |
102 | * Returns the dependencies of the project. | |
103 | * | |
104 | * @return the dependencies of the project | |
105 | */ | |
106 | public List getDependencies() | |
107 | { | |
108 | 30 | final List result = new ArrayList(); |
109 | 30 | if ( dependenciesInfo == null ) |
110 | { | |
111 | 0 | return result; |
112 | } | |
113 | 30 | final Iterator it = dependenciesInfo.iterator(); |
114 | 67 | while ( it.hasNext() ) |
115 | { | |
116 | 37 | DependencyInfo dependencyInfo = (DependencyInfo) it.next(); |
117 | 37 | result.add( dependencyInfo.getDependency() ); |
118 | 37 | } |
119 | 30 | return result; |
120 | } | |
121 | ||
122 | ||
123 | /** | |
124 | * Specify if the specified <tt>path</tt> is registered or not. | |
125 | * | |
126 | * @param path the relative path from the webapp root directory | |
127 | * @return true if the path is registered, false otherwise | |
128 | */ | |
129 | public boolean isRegistered( String path ) | |
130 | { | |
131 | 812 | return getFullStructure().contains( path ); |
132 | ||
133 | } | |
134 | ||
135 | /** | |
136 | * Registers the specified path for the specified owner. Returns <tt>true</tt> | |
137 | * if the path is not already registered, <tt>false</tt> otherwise. | |
138 | * | |
139 | * @param id the owner of the path | |
140 | * @param path the relative path from the webapp root directory | |
141 | * @return true if the file was registered successfully | |
142 | */ | |
143 | public boolean registerFile( String id, String path ) | |
144 | { | |
145 | 9 | if ( !isRegistered( path ) ) |
146 | { | |
147 | 8 | doRegister( id, path ); |
148 | 8 | return true; |
149 | } | |
150 | else | |
151 | { | |
152 | 1 | return false; |
153 | } | |
154 | } | |
155 | ||
156 | /** | |
157 | * Forces the registration of the specified path for the specified owner. If | |
158 | * the file is not registered yet, a simple registration is performed. If the | |
159 | * file already exists, the owner changes to the specified one. | |
160 | * <p/> | |
161 | * Beware that the semantic of the return boolean is different than the one | |
162 | * from {@link #registerFile(String, String)}; returns <tt>true</tt> if an | |
163 | * owner replacement was made and <tt>false</tt> if the file was simply registered | |
164 | * for the first time. | |
165 | * | |
166 | * @param id the owner of the path | |
167 | * @param path the relative path from the webapp root directory | |
168 | * @return false if the file did not exist, true if the owner was replaced | |
169 | */ | |
170 | public boolean registerFileForced( String id, String path ) | |
171 | { | |
172 | 27 | if ( !isRegistered( path ) ) |
173 | { | |
174 | 26 | doRegister( id, path ); |
175 | 26 | return false; |
176 | } | |
177 | else | |
178 | { | |
179 | // Force the switch to the new owner | |
180 | 1 | getStructure( getOwner( path ) ).remove( path ); |
181 | 1 | getStructure( id ).add( path ); |
182 | 1 | return true; |
183 | } | |
184 | ||
185 | } | |
186 | ||
187 | /** | |
188 | * Registers the specified path for the specified owner. Invokes | |
189 | * the <tt>callback</tt> with the result of the registration. | |
190 | * | |
191 | * @param id the owner of the path | |
192 | * @param path the relative path from the webapp root directory | |
193 | * @param callback the callback to invoke with the result of the registration | |
194 | * @throws IOException if the callback invocation throws an IOException | |
195 | */ | |
196 | public void registerFile( String id, String path, RegistrationCallback callback ) | |
197 | throws IOException | |
198 | { | |
199 | ||
200 | // If the file is already in the current structure, rejects it with the current owner | |
201 | 362 | if ( isRegistered( path ) ) |
202 | { | |
203 | 115 | callback.refused( id, path, getOwner( path ) ); |
204 | } | |
205 | else | |
206 | { | |
207 | 247 | doRegister( id, path ); |
208 | // This is a new file | |
209 | 247 | if ( cache.getOwner( path ) == null ) |
210 | { | |
211 | 216 | callback.registered( id, path ); |
212 | ||
213 | } // The file already belonged to this owner | |
214 | 31 | else if ( cache.getOwner( path ).equals( id ) ) |
215 | { | |
216 | 23 | callback.alreadyRegistered( id, path ); |
217 | } // The file belongs to another owner and it's known currently | |
218 | 8 | else if ( getOwners().contains( cache.getOwner( path ) ) ) |
219 | { | |
220 | 6 | callback.superseded( id, path, cache.getOwner( path ) ); |
221 | } // The file belongs to another owner and it's unknown | |
222 | else | |
223 | { | |
224 | 2 | callback.supersededUnknownOwner( id, path, cache.getOwner( path ) ); |
225 | } | |
226 | } | |
227 | 362 | } |
228 | ||
229 | /** | |
230 | * Returns the owner of the specified <tt>path</tt>. If the file is not | |
231 | * registered, returns <tt>null</tt> | |
232 | * | |
233 | * @param path the relative path from the webapp root directory | |
234 | * @return the owner or <tt>null</tt>. | |
235 | */ | |
236 | public String getOwner( String path ) | |
237 | { | |
238 | 413 | if ( !isRegistered( path ) ) |
239 | { | |
240 | 216 | return null; |
241 | } | |
242 | else | |
243 | { | |
244 | 197 | final Iterator it = registeredFiles.keySet().iterator(); |
245 | 541 | while ( it.hasNext() ) |
246 | { | |
247 | 541 | final String owner = (String) it.next(); |
248 | 541 | final PathSet structure = getStructure( owner ); |
249 | 541 | if ( structure.contains( path ) ) |
250 | { | |
251 | 197 | return owner; |
252 | } | |
253 | ||
254 | 344 | } |
255 | 0 | throw new IllegalStateException( |
256 | "Should not happen, path [" + path + "] is flagged as being registered but was not found." ); | |
257 | } | |
258 | ||
259 | } | |
260 | ||
261 | /** | |
262 | * Returns the owners. Note that this the returned {@link Set} may be | |
263 | * inconsistent since it represents a persistent cache across multiple | |
264 | * invocations. | |
265 | * <p/> | |
266 | * For instance, if an overlay was removed in this execution, it will be | |
267 | * still be there till the cache is cleaned. This happens when the clean | |
268 | * mojo is invoked. | |
269 | * | |
270 | * @return the list of owners | |
271 | */ | |
272 | public Set getOwners() | |
273 | { | |
274 | 8 | return registeredFiles.keySet(); |
275 | } | |
276 | ||
277 | /** | |
278 | * Returns all paths that have been registered so far. | |
279 | * | |
280 | * @return all registered path | |
281 | */ | |
282 | public PathSet getFullStructure() | |
283 | { | |
284 | 1093 | return allFiles; |
285 | } | |
286 | ||
287 | /** | |
288 | * Returns the list of registered files for the specified owner. | |
289 | * | |
290 | * @param id the owner | |
291 | * @return the list of files registered for that owner | |
292 | */ | |
293 | public PathSet getStructure( String id ) | |
294 | { | |
295 | 982 | PathSet pathSet = (PathSet) registeredFiles.get( id ); |
296 | 982 | if ( pathSet == null ) |
297 | { | |
298 | 98 | pathSet = new PathSet(); |
299 | 98 | registeredFiles.put( id, pathSet ); |
300 | } | |
301 | 982 | return pathSet; |
302 | } | |
303 | ||
304 | ||
305 | /** | |
306 | * Analyze the dependencies of the project using the specified callback. | |
307 | * | |
308 | * @param callback the callback to use to report the result of the analysis | |
309 | */ | |
310 | public void analyseDependencies( DependenciesAnalysisCallback callback ) | |
311 | { | |
312 | 15 | if ( callback == null ) |
313 | { | |
314 | 0 | throw new NullPointerException( "Callback could not be null." ); |
315 | } | |
316 | 15 | if ( cache == null ) |
317 | { | |
318 | // Could not analyze dependencies without a cache | |
319 | 0 | return; |
320 | } | |
321 | ||
322 | 15 | final List currentDependencies = new ArrayList( getDependencies() ); |
323 | 15 | final List previousDependencies = new ArrayList( cache.getDependencies() ); |
324 | 15 | final Iterator it = currentDependencies.listIterator(); |
325 | 33 | while ( it.hasNext() ) |
326 | { | |
327 | 18 | Dependency dependency = (Dependency) it.next(); |
328 | // Check if the dependency is there "as is" | |
329 | ||
330 | 18 | final Dependency matchingDependency = matchDependency( previousDependencies, dependency ); |
331 | 18 | if ( matchingDependency != null ) |
332 | { | |
333 | 14 | callback.unchangedDependency( dependency ); |
334 | // Handled so let's remove | |
335 | 14 | it.remove(); |
336 | 14 | previousDependencies.remove( matchingDependency ); |
337 | } | |
338 | else | |
339 | { | |
340 | // Try to get the dependency | |
341 | 4 | final Dependency previousDep = findDependency( dependency, previousDependencies ); |
342 | 4 | if ( previousDep == null ) |
343 | { | |
344 | 2 | callback.newDependency( dependency ); |
345 | 2 | it.remove(); |
346 | } | |
347 | 2 | else if ( !dependency.getVersion().equals( previousDep.getVersion() ) ) |
348 | { | |
349 | 1 | callback.updatedVersion( dependency, previousDep.getVersion() ); |
350 | 1 | it.remove(); |
351 | 1 | previousDependencies.remove( previousDep ); |
352 | } | |
353 | 1 | else if ( !dependency.getScope().equals( previousDep.getScope() ) ) |
354 | { | |
355 | 1 | callback.updatedScope( dependency, previousDep.getScope() ); |
356 | 1 | it.remove(); |
357 | 1 | previousDependencies.remove( previousDep ); |
358 | } | |
359 | 0 | else if ( dependency.isOptional() != previousDep.isOptional() ) |
360 | { | |
361 | 0 | callback.updatedOptionalFlag( dependency, previousDep.isOptional() ); |
362 | 0 | it.remove(); |
363 | 0 | previousDependencies.remove( previousDep ); |
364 | } | |
365 | else | |
366 | { | |
367 | 0 | callback.updatedUnknown( dependency, previousDep ); |
368 | 0 | it.remove(); |
369 | 0 | previousDependencies.remove( previousDep ); |
370 | } | |
371 | } | |
372 | 18 | } |
373 | 15 | final Iterator previousDepIt = previousDependencies.iterator(); |
374 | 18 | while ( previousDepIt.hasNext() ) |
375 | { | |
376 | 3 | Dependency dependency = (Dependency) previousDepIt.next(); |
377 | 3 | callback.removedDependency( dependency ); |
378 | 3 | } |
379 | 15 | } |
380 | ||
381 | /** | |
382 | * Registers the target file name for the specified artifact. | |
383 | * | |
384 | * @param artifact the artifact | |
385 | * @param targetFileName the target file name | |
386 | */ | |
387 | public void registerTargetFileName( Artifact artifact, String targetFileName ) | |
388 | { | |
389 | 55 | if ( dependenciesInfo != null ) |
390 | { | |
391 | 55 | final Iterator it = dependenciesInfo.iterator(); |
392 | 150 | while ( it.hasNext() ) |
393 | { | |
394 | 95 | DependencyInfo dependencyInfo = (DependencyInfo) it.next(); |
395 | 95 | if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) ) |
396 | { | |
397 | 51 | dependencyInfo.setTargetFileName( targetFileName ); |
398 | } | |
399 | 95 | } |
400 | } | |
401 | 55 | } |
402 | ||
403 | /** | |
404 | * Returns the cached target file name that matches the specified | |
405 | * dependency, that is the target file name of the previous run. | |
406 | * <p/> | |
407 | * The dependency object may have changed so the comparison is | |
408 | * based on basic attributes of the dependency. | |
409 | * | |
410 | * @param dependency a dependency | |
411 | * @return the target file name of the last run for this dependency | |
412 | */ | |
413 | public String getCachedTargetFileName( Dependency dependency ) | |
414 | { | |
415 | 3 | if ( cache == null ) |
416 | { | |
417 | 0 | return null; |
418 | } | |
419 | 3 | final Iterator it = cache.getDependenciesInfo().iterator(); |
420 | 3 | while ( it.hasNext() ) |
421 | { | |
422 | 3 | DependencyInfo dependencyInfo = (DependencyInfo) it.next(); |
423 | 3 | final Dependency dependency2 = dependencyInfo.getDependency(); |
424 | 3 | if ( StringUtils.equals( dependency.getGroupId(), dependency2.getGroupId() ) |
425 | && StringUtils.equals( dependency.getArtifactId(), dependency2.getArtifactId() ) | |
426 | && StringUtils.equals( dependency.getType(), dependency2.getType() ) | |
427 | && StringUtils.equals( dependency.getClassifier(), dependency2.getClassifier() ) ) | |
428 | { | |
429 | ||
430 | 3 | return dependencyInfo.getTargetFileName(); |
431 | ||
432 | } | |
433 | 0 | } |
434 | 0 | return null; |
435 | } | |
436 | ||
437 | // Private helpers | |
438 | ||
439 | private void doRegister( String id, String path ) | |
440 | { | |
441 | 281 | getFullStructure().add( path ); |
442 | 281 | getStructure( id ).add( path ); |
443 | 281 | } |
444 | ||
445 | /** | |
446 | * Find a dependency that is similar from the specified dependency. | |
447 | * | |
448 | * @param dependency the dependency to find | |
449 | * @param dependencies a list of dependencies | |
450 | * @return a similar dependency or <tt>null</tt> if no similar dependency is found | |
451 | */ | |
452 | private Dependency findDependency( Dependency dependency, List dependencies ) | |
453 | { | |
454 | 4 | final Iterator it = dependencies.iterator(); |
455 | 5 | while ( it.hasNext() ) |
456 | { | |
457 | 3 | Dependency dep = (Dependency) it.next(); |
458 | 3 | if ( dependency.getGroupId().equals( dep.getGroupId() ) |
459 | && dependency.getArtifactId().equals( dep.getArtifactId() ) | |
460 | && dependency.getType().equals( dep.getType() ) | |
461 | && ( ( dependency.getClassifier() == null && dep.getClassifier() == null ) | |
462 | || ( dependency.getClassifier() != null | |
463 | && dependency.getClassifier().equals( dep.getClassifier() ) ) ) ) | |
464 | { | |
465 | 2 | return dep; |
466 | } | |
467 | 1 | } |
468 | 2 | return null; |
469 | } | |
470 | ||
471 | private Dependency matchDependency( List dependencies, Dependency dependency ) | |
472 | { | |
473 | 18 | final Iterator it = dependencies.iterator(); |
474 | 22 | while ( it.hasNext() ) |
475 | { | |
476 | 18 | Dependency dep = (Dependency) it.next(); |
477 | 18 | if ( WarUtils.dependencyEquals( dep, dependency ) ) |
478 | { | |
479 | 14 | return dep; |
480 | } | |
481 | ||
482 | 4 | } |
483 | 4 | return null; |
484 | } | |
485 | ||
486 | ||
487 | private List createDependenciesInfoList( List dependencies ) | |
488 | { | |
489 | 126 | if ( dependencies == null ) |
490 | { | |
491 | 0 | return Collections.EMPTY_LIST; |
492 | } | |
493 | 126 | final List result = new ArrayList(); |
494 | 126 | final Iterator it = dependencies.iterator(); |
495 | 226 | while ( it.hasNext() ) |
496 | { | |
497 | 100 | Dependency dependency = (Dependency) it.next(); |
498 | 100 | result.add( new DependencyInfo( dependency ) ); |
499 | 100 | } |
500 | 126 | return result; |
501 | } | |
502 | ||
503 | ||
504 | private Object readResolve() | |
505 | { | |
506 | // the full structure should be resolved so let's rebuild it | |
507 | 8 | this.allFiles = new PathSet(); |
508 | 8 | final Iterator it = registeredFiles.values().iterator(); |
509 | 23 | while ( it.hasNext() ) |
510 | { | |
511 | 15 | PathSet pathSet = (PathSet) it.next(); |
512 | 15 | this.allFiles.addAll( pathSet ); |
513 | 15 | } |
514 | 8 | return this; |
515 | } | |
516 | ||
517 | /** | |
518 | * Callback interface to handle events related to filepath registration in | |
519 | * the webapp. | |
520 | */ | |
521 | public interface RegistrationCallback | |
522 | { | |
523 | ||
524 | ||
525 | /** | |
526 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
527 | * has been registered successfully. | |
528 | * <p/> | |
529 | * This means that the <tt>targetFilename</tt> was unknown and has been | |
530 | * registered successfully. | |
531 | * | |
532 | * @param ownerId the ownerId | |
533 | * @param targetFilename the relative path according to the root of the webapp | |
534 | * @throws IOException if an error occurred while handling this event | |
535 | */ | |
536 | void registered( String ownerId, String targetFilename ) | |
537 | throws IOException; | |
538 | ||
539 | /** | |
540 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
541 | * has already been registered. | |
542 | * <p/> | |
543 | * This means that the <tt>targetFilename</tt> was known and belongs to the | |
544 | * specified owner. | |
545 | * | |
546 | * @param ownerId the ownerId | |
547 | * @param targetFilename the relative path according to the root of the webapp | |
548 | * @throws IOException if an error occurred while handling this event | |
549 | */ | |
550 | void alreadyRegistered( String ownerId, String targetFilename ) | |
551 | throws IOException; | |
552 | ||
553 | /** | |
554 | * Called if the registration of the <tt>targetFilename</tt> for the | |
555 | * specified <tt>ownerId</tt> has been refused since the path already | |
556 | * belongs to the <tt>actualOwnerId</tt>. | |
557 | * <p/> | |
558 | * This means that the <tt>targetFilename</tt> was known and does not | |
559 | * belong to the specified owner. | |
560 | * | |
561 | * @param ownerId the ownerId | |
562 | * @param targetFilename the relative path according to the root of the webapp | |
563 | * @param actualOwnerId the actual owner | |
564 | * @throws IOException if an error occurred while handling this event | |
565 | */ | |
566 | void refused( String ownerId, String targetFilename, String actualOwnerId ) | |
567 | throws IOException; | |
568 | ||
569 | /** | |
570 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
571 | * has been registered successfully by superseding a <tt>deprecatedOwnerId</tt>, | |
572 | * that is the previous owner of the file. | |
573 | * <p/> | |
574 | * This means that the <tt>targetFilename</tt> was known but for another | |
575 | * owner. This usually happens after a project's configuration change. As a | |
576 | * result, the file has been registered successfully to the new owner. | |
577 | * | |
578 | * @param ownerId the ownerId | |
579 | * @param targetFilename the relative path according to the root of the webapp | |
580 | * @param deprecatedOwnerId the previous owner that does not exist anymore | |
581 | * @throws IOException if an error occurred while handling this event | |
582 | */ | |
583 | void superseded( String ownerId, String targetFilename, String deprecatedOwnerId ) | |
584 | throws IOException; | |
585 | ||
586 | /** | |
587 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
588 | * has been registered successfully by superseding a <tt>unknownOwnerId</tt>, | |
589 | * that is an owner that does not exist anymore in the current project. | |
590 | * <p/> | |
591 | * This means that the <tt>targetFilename</tt> was known but for an owner that | |
592 | * does not exist anymore. Hence the file has been registered successfully to | |
593 | * the new owner. | |
594 | * | |
595 | * @param ownerId the ownerId | |
596 | * @param targetFilename the relative path according to the root of the webapp | |
597 | * @param unknownOwnerId the previous owner that does not exist anymore | |
598 | * @throws IOException if an error occurred while handling this event | |
599 | */ | |
600 | void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId ) | |
601 | throws IOException; | |
602 | } | |
603 | ||
604 | /** | |
605 | * Callback interface to handle events related to dependencies analysis. | |
606 | */ | |
607 | public interface DependenciesAnalysisCallback | |
608 | { | |
609 | ||
610 | /** | |
611 | * Called if the dependency has not changed since the last build. | |
612 | * | |
613 | * @param dependency the dependency that hasn't changed | |
614 | */ | |
615 | void unchangedDependency( Dependency dependency ); | |
616 | ||
617 | /** | |
618 | * Called if a new dependency has been added since the last build. | |
619 | * | |
620 | * @param dependency the new dependency | |
621 | */ | |
622 | void newDependency( Dependency dependency ); | |
623 | ||
624 | /** | |
625 | * Called if the dependency has been removed since the last build. | |
626 | * | |
627 | * @param dependency the dependency that has been removed | |
628 | */ | |
629 | void removedDependency( Dependency dependency ); | |
630 | ||
631 | /** | |
632 | * Called if the version of the dependency has changed since the last build. | |
633 | * | |
634 | * @param dependency the dependency | |
635 | * @param previousVersion the previous version of the dependency | |
636 | */ | |
637 | void updatedVersion( Dependency dependency, String previousVersion ); | |
638 | ||
639 | /** | |
640 | * Called if the scope of the dependency has changed since the last build. | |
641 | * | |
642 | * @param dependency the dependency | |
643 | * @param previousScope the previous scope | |
644 | */ | |
645 | void updatedScope( Dependency dependency, String previousScope ); | |
646 | ||
647 | /** | |
648 | * Called if the optional flag of the dependency has changed since the | |
649 | * last build. | |
650 | * | |
651 | * @param dependency the dependency | |
652 | * @param previousOptional the previous optional flag | |
653 | */ | |
654 | void updatedOptionalFlag( Dependency dependency, boolean previousOptional ); | |
655 | ||
656 | /** | |
657 | * Called if the dependency has been updated for unknown reason. | |
658 | * | |
659 | * @param dependency the dependency | |
660 | * @param previousDep the previous dependency | |
661 | */ | |
662 | void updatedUnknown( Dependency dependency, Dependency previousDep ); | |
663 | ||
664 | } | |
665 | } |