/** Called when a module build that corresponds to this module set build has completed. */ /* package */ void notifyModuleBuild(IvyBuild newBuild) { try { // update module set build number getParent().updateNextBuildNumber(); // update actions Map<IvyModule, List<IvyBuild>> moduleBuilds = getModuleBuilds(); // actions need to be replaced atomically especially // given that two builds might complete simultaneously. synchronized (this) { boolean modified = false; List<Action> actions = getActions(); Set<Class<? extends AggregatableAction>> individuals = new HashSet<Class<? extends AggregatableAction>>(); for (Action a : actions) { if (a instanceof IvyAggregatedReport) { IvyAggregatedReport mar = (IvyAggregatedReport) a; mar.update(moduleBuilds, newBuild); individuals.add(mar.getIndividualActionType()); modified = true; } } // see if the new build has any new aggregatable action that we // haven't seen. for (AggregatableAction aa : newBuild.getActions(AggregatableAction.class)) { if (individuals.add(aa.getClass())) { // new AggregatableAction IvyAggregatedReport mar = aa.createAggregatedAction(this, moduleBuilds); mar.update(moduleBuilds, newBuild); actions.add(mar); modified = true; } } if (modified) { save(); getProject().updateTransientActions(); } } // symlink to this module build String moduleFsName = newBuild.getProject().getModuleName().toFileSystemName(); Util.createSymlink( getRootDir(), "../../modules/" + moduleFsName + "/builds/" + newBuild.getId() /*ugly!*/, moduleFsName, StreamTaskListener.NULL); } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to update " + this, e); } catch (InterruptedException e) { LOGGER.log(Level.WARNING, "Failed to update " + this, e); } }