/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.sokan.index.indexer; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.reuseware.sokan.ID; import org.reuseware.sokan.IndexRow; import org.reuseware.sokan.index.CommitCache; import org.reuseware.sokan.index.DependencyMap; import org.reuseware.sokan.index.util.IndexUtil; /** * The dependency manager is responsible for calculating the dependencies * between all indexers registered with an indexer manager. */ public class DependencyManager { private IndexerManager indexerManager; /** * Create a new dependency manager for the given index manager. * * @param indexerManager the index manager */ public DependencyManager(IndexerManager indexerManager) { this.indexerManager = indexerManager; } /** * Calculate the dependencies of indexers in the * context of the given commit cache. This method * expands the commit cache with the calculated result. * * @param indexers list of indexers of interest * @param cache the commit cache */ public void calculateDependenciesOfUpdatedArtifacts( List<Indexer> indexers, CommitCache cache) { // System.out.println("=== DEPENDENCIES ==="); List<ID> toConsider = new ArrayList<ID>(); toConsider.addAll(cache.getUpdateMap().keySet()); Set<ID> deletedIDs = cache.extractDeletedIDs(); toConsider.addAll(deletedIDs); for (ID artifactID : toConsider) { IndexRow oldRow = IndexUtil.INSTANCE.getIndex(artifactID); if (oldRow == null) { //this is a new artifact and there can not be old dependencies continue; } List<Indexer> indexersToAsk = new ArrayList<Indexer>(); if (cache.getUpdateMap().containsKey(artifactID)) { Iterator<Indexer> i = cache.getUpdateMap().get(artifactID).iterator(); while (i.hasNext()) { Indexer next = i.next(); if (indexers.contains(next)) { indexersToAsk.add(next); } } } else if (deletedIDs.contains(artifactID)) { indexersToAsk.addAll(indexers); } Map<ID, List<Indexer>> newDependencies = getDependencies(artifactID, indexersToAsk); //add new dependencies to cache for (Entry<ID, List<Indexer>> newEntry : newDependencies.entrySet()) { ID id = newEntry.getKey(); List<Indexer> newIndexers = newEntry.getValue(); List<Indexer> cacheIndexers = cache.getUpdateMap().get(id); if (cacheIndexers == null) { cache.getUpdateMap().put(id, newIndexers); } else { for (Indexer indexer : newEntry.getValue()) { if (!cacheIndexers.contains(indexer)) { cacheIndexers.add(indexer); } else { if (indexers.contains(indexer)) { System.err.println("ERROR: Indexer dependency in same phase " + indexer.getClass().getSimpleName()); } } } } } } // System.out.println("===================="); // System.out.println(); } private Map<ID, List<Indexer>> getDependencies(ID artifactID, List<Indexer> indexers) { Map<ID, List<Indexer>> directDependentArtifacts = new LinkedHashMap<ID, List<Indexer>>(); DependencyMap newDeps; for (Indexer indexer : indexers) { newDeps = new DependencyMap(); State.setCalcDep(); indexer.getDependent(artifactID, newDeps); //if (!newDeps.isEmpty()) { // System.out.println("- " + indexer.getClass().getSimpleName() + ":" + artifactID + ": " // + "(" + newDeps.getDependencies().size() + ") " + newDeps.getDependencies()); //} State.unsetCalcDep(); if (newDeps.isEmpty()) { continue; } for (Entry<ID, Set<String>> newDep : newDeps.getDependencies().entrySet()) { ID key = newDep.getKey(); if (directDependentArtifacts.containsKey(key)) { // try to add indexer id to Set<String> directDependentArtifacts.get(key).addAll( indexerManager.getIndexers(newDep.getValue(), true)); } else { // add complete mapping ID,List<String> to dependents-Map directDependentArtifacts.put( key, indexerManager.getIndexers(newDep.getValue(), true)); } } } return directDependentArtifacts; } }