/******************************************************************************* * Copyright (c) 2010, Cloudsmith Inc. * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the copyright holder * listed above, as the Initial Contributor under such license. The text of * such license is available at www.eclipse.org. ******************************************************************************/ package org.eclipse.buckminster.team; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.HashMap; import org.eclipse.buckminster.core.actor.IActionContext; import org.eclipse.buckminster.core.reader.AbstractReaderType; import org.eclipse.buckminster.core.reader.IReaderType; import org.eclipse.buckminster.core.reader.ITeamReaderType; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.team.core.RepositoryProvider; /** * A base class of team actors' specific perform contexts capturing the common * functionality - mapping of {@link RepositoryProvider} IDs to * {@link ITeamReaderType}s and collecting of errors. The team actors are * expected to extend this class with data/functionality specific to them. * * @author michal.ruzicka@cloudsmith.com */ public class TeamPerformContext { // an instance of ITeamReaderType used for caching of negative results // of reader type lookups private static final ITeamReaderType NO_READER_TYPE = (ITeamReaderType) Proxy.newProxyInstance(TeamPerformContext.class.getClassLoader(), new Class<?>[] { ITeamReaderType.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw new UnsupportedOperationException(); } }); private final IActionContext actionContext; private HashMap<String, ITeamReaderType> readerTypeCache = new HashMap<String, ITeamReaderType>(); private ArrayList<IStatus> statuses = new ArrayList<IStatus>(); public TeamPerformContext(IActionContext actionContext) { this.actionContext = actionContext; } /** * Return the collected statuses wrapped in a multi status and clear the * list of the collected statuses. * * @param message * a message to use for the wrapping multi status * @return the multi status wrapping the collected statuses */ public IStatus collectedStatus(String message) { IStatus status = AbstractTeamActor.createMultiStatus(message, statuses.toArray(new IStatus[statuses.size()])); statuses.clear(); return status; } /** * Add the given status to a list of collected statuses but only if the * given status is not {@link IStatus#isOK()}. * * @param status * the status to add to the list of collected statuses */ public void collectStatus(IStatus status) { if (!status.isOK()) statuses.add(status); } /** * Return the {@link IActionContext} this <code>TeamPerformContext</code> is * linked to. * * @return the action context this team perform context is linked to */ public IActionContext getActionContext() { return actionContext; } /** * Return an implementation of {@link ITeamReaderType} capable of handling * resources associated with {@link RepositoryProvider}s with the given ID.<br/> * Note that this method only uses a cache of provider ID to reader type * mappings populated by the * {@link #getReaderTypeForRepositoryProvider(String)} method. It is * considered to be an error if there is no appropriate mapping found in the * cache for the given repository provider ID - an * <code>IllegalStateException</code> exception is thrown in such case. * * @param providerID * the repository provider ID to get the reader type for * @return the reader type corresponding to the given * <code>providerID</code> or <code>null</code> if such a reader * type does not exist * @throws IllegalStateException * if there is no appropriate repository provider ID to reader * type mapping found in the cache */ public ITeamReaderType getCachedReaderTypeForRepositoryProvider(String providerID) throws IllegalStateException { ITeamReaderType readerType = readerTypeCache.get(providerID); if (readerType == null) throw new IllegalStateException(); if (readerType == NO_READER_TYPE) return null; return readerType; } /** * Return an implementation of {@link ITeamReaderType} capable of handling * resources associated with a {@link RepositoryProvider}s with the given * ID.<br/> * Note that this method performs caching of the provider ID to reader type * mappings. The cached mappings are used by both this method and * {@link #getCachedReaderTypeForRepositoryProvider(String)} which uses them * exclusively. * * @param providerID * the repository provider ID to get the reader type for * @return the reader type corresponding to the given * <code>providerID</code> or <code>null</code> if such a reader * type does not exist * @throws CoreException */ public ITeamReaderType getReaderTypeForRepositoryProvider(String providerID) throws CoreException { ITeamReaderType readerType = readerTypeCache.get(providerID); if (readerType == null) { IReaderType baseReaderType = AbstractReaderType.getTypeForRepositoryProvider(providerID); readerType = (baseReaderType != null && baseReaderType instanceof ITeamReaderType) ? (ITeamReaderType) baseReaderType : NO_READER_TYPE; readerTypeCache.put(providerID, readerType); } if (readerType == NO_READER_TYPE) return null; return readerType; } /** * Return <code>true</code> if there is at least one status in the list of * collected statuses. * * @return <code>true</code> if there is at least one status in the list of * collected statuses, <code>false</code> otherwise */ public boolean hasErrors() { return !statuses.isEmpty(); } }