Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
WebappStructure |
|
| 2.46875;2,469 | ||||
WebappStructure$DependenciesAnalysisCallback |
|
| 2.46875;2,469 | ||||
WebappStructure$RegistrationCallback |
|
| 2.46875;2,469 |
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 1006058 2010-10-08 22:43:15Z dennisl $ | |
45 | */ | |
46 | public class WebappStructure | |
47 | { | |
48 | ||
49 | private Map registeredFiles; | |
50 | ||
51 | private List dependenciesInfo; | |
52 | ||
53 | 122 | 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 | 59 | { |
64 | 59 | this.dependenciesInfo = createDependenciesInfoList( dependencies ); |
65 | 59 | this.registeredFiles = new HashMap(); |
66 | 59 | this.cache = null; |
67 | ||
68 | 59 | } |
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 | 63 | { |
78 | 63 | this.dependenciesInfo = createDependenciesInfoList( dependencies ); |
79 | 63 | this.registeredFiles = new HashMap(); |
80 | 63 | if ( cache == null ) |
81 | { | |
82 | 52 | this.cache = new WebappStructure( dependencies ); |
83 | ||
84 | } | |
85 | else | |
86 | { | |
87 | 11 | this.cache = cache; |
88 | } | |
89 | 63 | } |
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 | 801 | 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 | 26 | if ( !isRegistered( path ) ) |
173 | { | |
174 | 25 | doRegister( id, path ); |
175 | 25 | 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 | 357 | if ( isRegistered( path ) ) |
202 | { | |
203 | 115 | callback.refused( id, path, getOwner( path ) ); |
204 | } | |
205 | else | |
206 | { | |
207 | 242 | doRegister( id, path ); |
208 | // This is a new file | |
209 | 242 | if ( cache.getOwner( path ) == null ) |
210 | { | |
211 | 211 | 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 | 357 | } |
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 | 408 | if ( !isRegistered( path ) ) |
239 | { | |
240 | 211 | 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 | 1076 | 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 | 972 | PathSet pathSet = (PathSet) registeredFiles.get( id ); |
296 | 972 | if ( pathSet == null ) |
297 | { | |
298 | 96 | pathSet = new PathSet(); |
299 | 96 | registeredFiles.put( id, pathSet ); |
300 | } | |
301 | 972 | 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 | 54 | final Iterator it = dependenciesInfo.iterator(); |
390 | 148 | while ( it.hasNext() ) |
391 | { | |
392 | 94 | DependencyInfo dependencyInfo = (DependencyInfo) it.next(); |
393 | 94 | if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) ) |
394 | { | |
395 | 50 | dependencyInfo.setTargetFileName( targetFileName ); |
396 | } | |
397 | 94 | } |
398 | 54 | } |
399 | ||
400 | /** | |
401 | * Returns the cached target file name that matches the specified | |
402 | * dependency, that is the target file name of the previous run. | |
403 | * <p/> | |
404 | * The dependency object may have changed so the comparison is | |
405 | * based on basic attributes of the dependency. | |
406 | * | |
407 | * @param dependency a dependency | |
408 | * @return the target file name of the last run for this dependency | |
409 | */ | |
410 | public String getCachedTargetFileName( Dependency dependency ) | |
411 | { | |
412 | 3 | if ( cache == null ) |
413 | { | |
414 | 0 | return null; |
415 | } | |
416 | 3 | final Iterator it = cache.getDependenciesInfo().iterator(); |
417 | 3 | while ( it.hasNext() ) |
418 | { | |
419 | 3 | DependencyInfo dependencyInfo = (DependencyInfo) it.next(); |
420 | 3 | final Dependency dependency2 = dependencyInfo.getDependency(); |
421 | 3 | if ( StringUtils.equals( dependency.getGroupId(), dependency2.getGroupId() ) |
422 | && StringUtils.equals( dependency.getArtifactId(), dependency2.getArtifactId() ) | |
423 | && StringUtils.equals( dependency.getType(), dependency2.getType() ) | |
424 | && StringUtils.equals( dependency.getClassifier(), dependency2.getClassifier() ) ) | |
425 | { | |
426 | ||
427 | 3 | return dependencyInfo.getTargetFileName(); |
428 | ||
429 | } | |
430 | 0 | } |
431 | 0 | return null; |
432 | } | |
433 | ||
434 | // Private helpers | |
435 | ||
436 | private void doRegister( String id, String path ) | |
437 | { | |
438 | 275 | getFullStructure().add( path ); |
439 | 275 | getStructure( id ).add( path ); |
440 | 275 | } |
441 | ||
442 | /** | |
443 | * Find a dependency that is similar from the specified dependency. | |
444 | * | |
445 | * @param dependency the dependency to find | |
446 | * @param dependencies a list of dependencies | |
447 | * @return a similar dependency or <tt>null</tt> if no similar dependency is found | |
448 | */ | |
449 | private Dependency findDependency( Dependency dependency, List dependencies ) | |
450 | { | |
451 | 4 | final Iterator it = dependencies.iterator(); |
452 | 5 | while ( it.hasNext() ) |
453 | { | |
454 | 3 | Dependency dep = (Dependency) it.next(); |
455 | 3 | if ( dependency.getGroupId().equals( dep.getGroupId() ) |
456 | && dependency.getArtifactId().equals( dep.getArtifactId() ) | |
457 | && dependency.getType().equals( dep.getType() ) | |
458 | && ( ( dependency.getClassifier() == null && dep.getClassifier() == null ) | |
459 | || ( dependency.getClassifier() != null | |
460 | && dependency.getClassifier().equals( dep.getClassifier() ) ) ) ) | |
461 | { | |
462 | 2 | return dep; |
463 | } | |
464 | 1 | } |
465 | 2 | return null; |
466 | } | |
467 | ||
468 | private Dependency matchDependency( List dependencies, Dependency dependency ) | |
469 | { | |
470 | 18 | final Iterator it = dependencies.iterator(); |
471 | 22 | while ( it.hasNext() ) |
472 | { | |
473 | 18 | Dependency dep = (Dependency) it.next(); |
474 | 18 | if ( WarUtils.dependencyEquals( dep, dependency ) ) |
475 | { | |
476 | 14 | return dep; |
477 | } | |
478 | ||
479 | 4 | } |
480 | 4 | return null; |
481 | } | |
482 | ||
483 | ||
484 | private List createDependenciesInfoList( List dependencies ) | |
485 | { | |
486 | 122 | if ( dependencies == null ) |
487 | { | |
488 | 0 | return Collections.EMPTY_LIST; |
489 | } | |
490 | 122 | final List result = new ArrayList(); |
491 | 122 | final Iterator it = dependencies.iterator(); |
492 | 220 | while ( it.hasNext() ) |
493 | { | |
494 | 98 | Dependency dependency = (Dependency) it.next(); |
495 | 98 | result.add( new DependencyInfo( dependency ) ); |
496 | 98 | } |
497 | 122 | return result; |
498 | } | |
499 | ||
500 | ||
501 | private Object readResolve() | |
502 | { | |
503 | // the full structure should be resolved so let's rebuild it | |
504 | 8 | this.allFiles = new PathSet(); |
505 | 8 | final Iterator it = registeredFiles.values().iterator(); |
506 | 23 | while ( it.hasNext() ) |
507 | { | |
508 | 15 | PathSet pathSet = (PathSet) it.next(); |
509 | 15 | this.allFiles.addAll( pathSet ); |
510 | 15 | } |
511 | 8 | return this; |
512 | } | |
513 | ||
514 | /** | |
515 | * Callback interface to handle events related to filepath registration in | |
516 | * the webapp. | |
517 | */ | |
518 | public interface RegistrationCallback | |
519 | { | |
520 | ||
521 | ||
522 | /** | |
523 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
524 | * has been registered successfully. | |
525 | * <p/> | |
526 | * This means that the <tt>targetFilename</tt> was unknown and has been | |
527 | * registered successfully. | |
528 | * | |
529 | * @param ownerId the ownerId | |
530 | * @param targetFilename the relative path according to the root of the webapp | |
531 | * @throws IOException if an error occurred while handling this event | |
532 | */ | |
533 | void registered( String ownerId, String targetFilename ) | |
534 | throws IOException; | |
535 | ||
536 | /** | |
537 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
538 | * has already been registered. | |
539 | * <p/> | |
540 | * This means that the <tt>targetFilename</tt> was known and belongs to the | |
541 | * specified owner. | |
542 | * | |
543 | * @param ownerId the ownerId | |
544 | * @param targetFilename the relative path according to the root of the webapp | |
545 | * @throws IOException if an error occurred while handling this event | |
546 | */ | |
547 | void alreadyRegistered( String ownerId, String targetFilename ) | |
548 | throws IOException; | |
549 | ||
550 | /** | |
551 | * Called if the registration of the <tt>targetFilename</tt> for the | |
552 | * specified <tt>ownerId</tt> has been refused since the path already | |
553 | * belongs to the <tt>actualOwnerId</tt>. | |
554 | * <p/> | |
555 | * This means that the <tt>targetFilename</tt> was known and does not | |
556 | * belong to the specified owner. | |
557 | * | |
558 | * @param ownerId the ownerId | |
559 | * @param targetFilename the relative path according to the root of the webapp | |
560 | * @param actualOwnerId the actual owner | |
561 | * @throws IOException if an error occurred while handling this event | |
562 | */ | |
563 | void refused( String ownerId, String targetFilename, String actualOwnerId ) | |
564 | throws IOException; | |
565 | ||
566 | /** | |
567 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
568 | * has been registered successfully by superseding a <tt>deprecatedOwnerId</tt>, | |
569 | * that is the previous owner of the file. | |
570 | * <p/> | |
571 | * This means that the <tt>targetFilename</tt> was known but for another | |
572 | * owner. This usually happens after a project's configuration change. As a | |
573 | * result, the file has been registered successfully to the new owner. | |
574 | * | |
575 | * @param ownerId the ownerId | |
576 | * @param targetFilename the relative path according to the root of the webapp | |
577 | * @param deprecatedOwnerId the previous owner that does not exist anymore | |
578 | * @throws IOException if an error occurred while handling this event | |
579 | */ | |
580 | void superseded( String ownerId, String targetFilename, String deprecatedOwnerId ) | |
581 | throws IOException; | |
582 | ||
583 | /** | |
584 | * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> | |
585 | * has been registered successfully by superseding a <tt>unknownOwnerId</tt>, | |
586 | * that is an owner that does not exist anymore in the current project. | |
587 | * <p/> | |
588 | * This means that the <tt>targetFilename</tt> was known but for an owner that | |
589 | * does not exist anymore. Hence the file has been registered successfully to | |
590 | * the new owner. | |
591 | * | |
592 | * @param ownerId the ownerId | |
593 | * @param targetFilename the relative path according to the root of the webapp | |
594 | * @param unknownOwnerId the previous owner that does not exist anymore | |
595 | * @throws IOException if an error occurred while handling this event | |
596 | */ | |
597 | void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId ) | |
598 | throws IOException; | |
599 | } | |
600 | ||
601 | /** | |
602 | * Callback interface to handle events related to dependencies analysis. | |
603 | */ | |
604 | public interface DependenciesAnalysisCallback | |
605 | { | |
606 | ||
607 | /** | |
608 | * Called if the dependency has not changed since the last build. | |
609 | * | |
610 | * @param dependency the dependency that hasn't changed | |
611 | */ | |
612 | void unchangedDependency( Dependency dependency ); | |
613 | ||
614 | /** | |
615 | * Called if a new dependency has been added since the last build. | |
616 | * | |
617 | * @param dependency the new dependency | |
618 | */ | |
619 | void newDependency( Dependency dependency ); | |
620 | ||
621 | /** | |
622 | * Called if the dependency has been removed since the last build. | |
623 | * | |
624 | * @param dependency the dependency that has been removed | |
625 | */ | |
626 | void removedDependency( Dependency dependency ); | |
627 | ||
628 | /** | |
629 | * Called if the version of the dependency has changed since the last build. | |
630 | * | |
631 | * @param dependency the dependency | |
632 | * @param previousVersion the previous version of the dependency | |
633 | */ | |
634 | void updatedVersion( Dependency dependency, String previousVersion ); | |
635 | ||
636 | /** | |
637 | * Called if the scope of the dependency has changed since the last build. | |
638 | * | |
639 | * @param dependency the dependency | |
640 | * @param previousScope the previous scope | |
641 | */ | |
642 | void updatedScope( Dependency dependency, String previousScope ); | |
643 | ||
644 | /** | |
645 | * Called if the optional flag of the dependency has changed since the | |
646 | * last build. | |
647 | * | |
648 | * @param dependency the dependency | |
649 | * @param previousOptional the previous optional flag | |
650 | */ | |
651 | void updatedOptionalFlag( Dependency dependency, boolean previousOptional ); | |
652 | ||
653 | /** | |
654 | * Called if the dependency has been updated for unknown reason. | |
655 | * | |
656 | * @param dependency the dependency | |
657 | * @param previousDep the previous dependency | |
658 | */ | |
659 | void updatedUnknown( Dependency dependency, Dependency previousDep ); | |
660 | ||
661 | } | |
662 | } |