/******************************************************************************* * 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.Collection; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.reuseware.sokan.ID; import org.reuseware.sokan.index.CommitCache; import org.reuseware.sokan.index.persister.PersistencyManager; import org.reuseware.sokan.index.util.CoreUtil; /** * The index manager manages the registration of indexers. */ public class IndexerManager { private MetaDataManager metaDataManager; private DependencyManager depManager; private IndexerSorter indexerSorter; private MultiPhaseCommit multiPhase; private Map<String, Indexer> allNormalIndexers = null; private Map<String, Indexer> allCalledIndexers = null; private Map<String, IndexerConfiguration> allIndexerConfigs; private Map<String, Object> loadOptions = null; /** * Creates a new index manager that uses the given * persistency manager for index access. * * @param persistencyManager the persistency manager */ public IndexerManager(PersistencyManager persistencyManager) { initIndexers(); initLoadOptions(); indexerSorter = new IndexerSorter(); metaDataManager = new MetaDataManager(getIndexers(null, false)); depManager = new DependencyManager(this); multiPhase = new MultiPhaseCommit(depManager, metaDataManager, persistencyManager, this); } /** * Set a load option that will be used for loading and * saving resources. * * @param option the option to set * @param value the value of the option */ public void addLoadOption(String option, boolean value) { loadOptions.put(option, value); } /** * Registers a new indexer. * * @param indexerConfiguration the index configuration that contains * the indexer with its dependencies */ public void addIndexer(IndexerConfiguration indexerConfiguration) { String indexerID = indexerConfiguration.getId(); Indexer indexer = indexerConfiguration.getIndexer(); allIndexerConfigs.put(indexerID, indexerConfiguration); if (indexer instanceof CalledIndexer) { allCalledIndexers.put(indexerID, indexer); } else { allNormalIndexers.put(indexerID, indexer); } } /** * @return all registered indexers */ public List<IndexerConfiguration> getIndexerConfigurations() { return new ArrayList<IndexerConfiguration>(allIndexerConfigs.values()); } /** * Commits the given index cache to the index. * * @param cache the index cache * @param monitor a monitor to record progress * * @return the IDs of all artifacts that have been updated in this commit */ public Set<ID> performCommit(CommitCache cache, IProgressMonitor monitor) { ResourceSet resourceSet = createNewResourceSet(); int durationEstimation = cache.extractAllIDs().size() * getIndexerConfigurations().size() * 4; monitor.beginTask("Indexing Workspace", durationEstimation); Set<ID> delta = multiPhase.start(cache, resourceSet, 0, monitor); monitor.done(); return delta; } private void initIndexers() { if (allNormalIndexers == null) { allNormalIndexers = new LinkedHashMap<String, Indexer>(); allCalledIndexers = new LinkedHashMap<String, Indexer>(); allIndexerConfigs = new LinkedHashMap<String, IndexerConfiguration>(); List<IndexerConfiguration> configs = CoreUtil.findIndexer(); Indexer indexer; String indexerID; for (IndexerConfiguration elem : configs) { indexerID = elem.getId(); indexer = elem.getIndexer(); allIndexerConfigs.put(indexerID, elem); if (indexer instanceof CalledIndexer) { allCalledIndexers.put(indexerID, indexer); } else { allNormalIndexers.put(indexerID, indexer); } } } } private void initLoadOptions() { if (loadOptions == null) { loadOptions = CoreUtil.findLoadOptions(); } } /** * Finds the indexers with the given IDs. * * @param indexerIDs the indexers' IDs * @param includeCalledIndexers true if called indexers should be included * @return the indexers with the given IDs */ public List<Indexer> getIndexers(Collection<String> indexerIDs, boolean includeCalledIndexers) { boolean allIndexersWanted = (indexerIDs == null || indexerIDs.size() == 0); if (allIndexersWanted && !includeCalledIndexers) { return new ArrayList<Indexer>(allNormalIndexers.values()); } Map<String, Indexer> allIndexers = new LinkedHashMap<String, Indexer>(); allIndexers.putAll(allNormalIndexers); allIndexers.putAll(allCalledIndexers); if (allIndexersWanted) { return new ArrayList<Indexer>(allIndexers.values()); } List<Indexer> myIndexers = new ArrayList<Indexer>(); Indexer indexer; for (String indexerID : indexerIDs) { indexer = allIndexers.get(indexerID); if (indexer != null) { myIndexers.add(indexer); } } return myIndexers; } /** * Finds the indexer with the given IDs. * * @param indexerID the indexer's IDs * @return the indexer with the given ID */ public Indexer getIndexer(String indexerID) { Indexer indexer = allNormalIndexers.get(indexerID); if (indexer != null) { return indexer; } indexer = allCalledIndexers.get(indexerID); return indexer; } /** * @param indexer the indexer * @return ID of the indexer */ public String getIndexerID(Indexer indexer) { for (String indexerID : allNormalIndexers.keySet()) { if (allNormalIndexers.get(indexerID).equals(indexer)) { return indexerID; } } for (String indexerID : allCalledIndexers.keySet()) { if (allCalledIndexers.get(indexerID).equals(indexer)) { return indexerID; } } return null; } /** * @return time stamp of the current commit */ public String getTimeStamp() { return multiPhase.getCommitTimeStamp(); } /** * Sorts the given list of indexers according to commit phases. * * @param indexerList list of indexers * @return sorted list of index sub-lists */ public List<List<Indexer>> sortByPhases(List<Indexer> indexerList) { if (indexerList == null) { return null; } List<IndexerConfiguration> cofigList = getIndexerConfigurations(indexerList); List<List<IndexerConfiguration>> sortedConfigs = indexerSorter.sort(cofigList); List<List<Indexer>> sortedIndexer; sortedIndexer = new ArrayList<List<Indexer>>(); List<String> commitPhaseIDs; for (List<IndexerConfiguration> phase : sortedConfigs) { commitPhaseIDs = new ArrayList<String>(); for (IndexerConfiguration iConfig : phase) { String indexerID = iConfig.getId(); commitPhaseIDs.add(indexerID); } sortedIndexer.add(new LinkedList<Indexer>( getIndexers(commitPhaseIDs, false))); } return sortedIndexer; } private List<IndexerConfiguration> getIndexerConfigurations( Collection<Indexer> indexers) { boolean allIndexersWanted = (indexers == null || indexers.size() == 0); if (allIndexersWanted) { return new ArrayList<IndexerConfiguration>(allIndexerConfigs.values()); } List<IndexerConfiguration> indexerConfigs = new ArrayList<IndexerConfiguration>(); IndexerConfiguration cofig; for (Indexer indexer : indexers) { cofig = allIndexerConfigs.get(getIndexerID(indexer)); if (cofig != null) { indexerConfigs.add(cofig); } } return indexerConfigs; } /** * @return the depManager */ public DependencyManager getDepManager() { return depManager; } /** * @return true if indexing is in progress */ public boolean isIndexing() { return State.isCreating(); } /** * @return true if dependency calculation is in progress */ public boolean isCalculatingDependencies() { return State.isCalculatingDependencies(); } /** * Registers a new load option. * * @param key the option's key * @param value the option's value */ public void addLoadOption(String key, Object value) { loadOptions.put(key, value); } /** * Initializes a new resource set with the registered * load options. * * @return the new resource set */ public ResourceSet createNewResourceSet() { ResourceSet resourceSet = new ResourceSetImpl(); resourceSet.getLoadOptions().putAll(loadOptions); return resourceSet; } }