package org.jetbrains.idea.svn.api; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.add.AddClient; import org.jetbrains.idea.svn.annotate.AnnotateClient; import org.jetbrains.idea.svn.browse.BrowseClient; import org.jetbrains.idea.svn.change.ChangeListClient; import org.jetbrains.idea.svn.checkin.CheckinClient; import org.jetbrains.idea.svn.checkin.ImportClient; import org.jetbrains.idea.svn.checkout.CheckoutClient; import org.jetbrains.idea.svn.checkout.ExportClient; import org.jetbrains.idea.svn.cleanup.CleanupClient; import org.jetbrains.idea.svn.conflict.ConflictClient; import org.jetbrains.idea.svn.content.ContentClient; import org.jetbrains.idea.svn.copy.CopyMoveClient; import org.jetbrains.idea.svn.delete.DeleteClient; import org.jetbrains.idea.svn.diff.DiffClient; import org.jetbrains.idea.svn.history.HistoryClient; import org.jetbrains.idea.svn.info.InfoClient; import org.jetbrains.idea.svn.integrate.MergeClient; import org.jetbrains.idea.svn.lock.LockClient; import org.jetbrains.idea.svn.properties.PropertyClient; import org.jetbrains.idea.svn.revert.RevertClient; import org.jetbrains.idea.svn.status.StatusClient; import org.jetbrains.idea.svn.update.RelocateClient; import org.jetbrains.idea.svn.update.UpdateClient; import org.jetbrains.idea.svn.upgrade.UpgradeClient; import org.tmatesoft.svn.core.wc.ISVNStatusFileProvider; import java.util.Map; /** * @author Konstantin Kolosovsky. */ public abstract class ClientFactory { @NotNull protected SvnVcs myVcs; protected AddClient addClient; protected AnnotateClient annotateClient; protected ContentClient contentClient; protected HistoryClient historyClient; protected RevertClient revertClient; protected DeleteClient deleteClient; protected StatusClient statusClient; protected InfoClient infoClient; protected CopyMoveClient copyMoveClient; protected ConflictClient conflictClient; protected PropertyClient propertyClient; protected MergeClient mergeClient; protected ChangeListClient changeListClient; protected CheckoutClient checkoutClient; protected LockClient myLockClient; protected CleanupClient myCleanupClient; protected RelocateClient myRelocateClient; protected VersionClient myVersionClient; protected ImportClient myImportClient; protected ExportClient myExportClient; protected UpgradeClient myUpgradeClient; protected BrowseClient myBrowseClient; protected DiffClient myDiffClient; protected CheckinClient myCheckinClient; protected RepositoryFeaturesClient myRepositoryFeaturesClient; @NotNull private final Map<Class, Class> myClientImplementations = ContainerUtil.newHashMap(); protected ClientFactory(@NotNull SvnVcs vcs) { myVcs = vcs; setup(); } protected abstract void setup(); protected <T extends SvnClient> void put(@NotNull Class<T> type, @NotNull Class<? extends T> implementation) { myClientImplementations.put(type, implementation); } @SuppressWarnings("unchecked") @NotNull protected <T extends SvnClient> Class<? extends T> get(@NotNull Class<T> type) { Class<? extends T> implementation = myClientImplementations.get(type); if (implementation == null) { throw new IllegalArgumentException("No implementation registered for " + type); } return implementation; } /** * TODO: Provide more robust way for the default settings here - probably some default Command instance could be used. */ @NotNull public <T extends SvnClient> T create(@NotNull Class<T> type, boolean isActive) { T client = prepare(ReflectionUtil.newInstance(get(type))); client.setIsActive(isActive); return client; } @NotNull public AddClient createAddClient() { return prepare(addClient); } @NotNull public AnnotateClient createAnnotateClient() { return prepare(annotateClient); } @NotNull public ContentClient createContentClient() { return prepare(contentClient); } @NotNull public HistoryClient createHistoryClient() { return prepare(historyClient); } @NotNull public RevertClient createRevertClient() { return prepare(revertClient); } @NotNull public StatusClient createStatusClient() { return prepare(statusClient); } @NotNull public StatusClient createStatusClient(@Nullable ISVNStatusFileProvider provider, @NotNull ProgressTracker handler) { return createStatusClient(); } @NotNull public InfoClient createInfoClient() { return prepare(infoClient); } // TODO: Update this in same like other clients - move to corresponding package, rename clients // New instances should be always created by this method, as setXxx() methods are currently used in update logic @NotNull public abstract UpdateClient createUpdateClient(); @NotNull public DeleteClient createDeleteClient() { return prepare(deleteClient); } @NotNull public CopyMoveClient createCopyMoveClient() { return prepare(copyMoveClient); } @NotNull public ConflictClient createConflictClient() { return prepare(conflictClient); } @NotNull public PropertyClient createPropertyClient() { return prepare(propertyClient); } @NotNull public MergeClient createMergeClient() { return prepare(mergeClient); } @NotNull public ChangeListClient createChangeListClient() { return prepare(changeListClient); } @NotNull public CheckoutClient createCheckoutClient() { return prepare(checkoutClient); } @NotNull public LockClient createLockClient() { return prepare(myLockClient); } @NotNull public CleanupClient createCleanupClient() { return prepare(myCleanupClient); } @NotNull public RelocateClient createRelocateClient() { return prepare(myRelocateClient); } @NotNull public VersionClient createVersionClient() { return prepare(myVersionClient); } @NotNull public ImportClient createImportClient() { return prepare(myImportClient); } @NotNull public ExportClient createExportClient() { return prepare(myExportClient); } @NotNull public UpgradeClient createUpgradeClient() { return prepare(myUpgradeClient); } @NotNull public BrowseClient createBrowseClient() { return prepare(myBrowseClient); } @NotNull public DiffClient createDiffClient() { return prepare(myDiffClient); } @NotNull public CheckinClient createCheckinClient() { return prepare(myCheckinClient); } @NotNull public RepositoryFeaturesClient createRepositoryFeaturesClient() { return prepare(myRepositoryFeaturesClient); } @NotNull protected <T extends SvnClient> T prepare(@NotNull T client) { client.setVcs(myVcs); client.setFactory(this); client.setIsActive(true); return client; } }