| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.jetbrains.idea.svn.dialogs; |
| |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.progress.ProgressIndicator; |
| import com.intellij.openapi.progress.Task; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.vcs.AbstractVcsHelper; |
| import com.intellij.openapi.vcs.ProjectLevelVcsManager; |
| import com.intellij.openapi.vcs.VcsException; |
| import com.intellij.openapi.vcs.changes.ChangeListManager; |
| import com.intellij.openapi.vcs.changes.LocalChangeList; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.vcsUtil.VcsUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.idea.svn.SvnBundle; |
| import org.jetbrains.idea.svn.SvnUtil; |
| import org.jetbrains.idea.svn.SvnVcs; |
| import org.jetbrains.idea.svn.WorkingCopyFormat; |
| import org.jetbrains.idea.svn.api.ClientFactory; |
| import org.jetbrains.idea.svn.api.EventAction; |
| import org.jetbrains.idea.svn.api.ProgressEvent; |
| import org.jetbrains.idea.svn.api.ProgressTracker; |
| import org.tmatesoft.svn.core.SVNCancelException; |
| import org.tmatesoft.svn.core.SVNException; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| public class SvnFormatWorker extends Task.Backgroundable { |
| |
| private static final Logger LOG = Logger.getInstance(SvnFormatWorker.class); |
| |
| private List<Throwable> myExceptions; |
| private final Project myProject; |
| @NotNull private final WorkingCopyFormat myNewFormat; |
| private final List<WCInfo> myWcInfos; |
| private List<LocalChangeList> myBeforeChangeLists; |
| private final SvnVcs myVcs; |
| |
| public SvnFormatWorker(final Project project, @NotNull final WorkingCopyFormat newFormat, final List<WCInfo> wcInfos) { |
| super(project, SvnBundle.message("action.change.wcopy.format.task.title"), false, DEAF); |
| myProject = project; |
| myNewFormat = newFormat; |
| myExceptions = new ArrayList<Throwable>(); |
| myWcInfos = wcInfos; |
| myVcs = SvnVcs.getInstance(myProject); |
| } |
| |
| public SvnFormatWorker(final Project project, @NotNull final WorkingCopyFormat newFormat, final WCInfo wcInfo) { |
| this(project, newFormat, Collections.singletonList(wcInfo)); |
| } |
| |
| public boolean haveStuffToConvert() { |
| return ! myWcInfos.isEmpty(); |
| } |
| |
| @Override |
| public void onCancel() { |
| onSuccess(); |
| } |
| |
| @Override |
| public void onSuccess() { |
| if (myProject.isDisposed()) { |
| return; |
| } |
| |
| if (! myExceptions.isEmpty()) { |
| final List<String> messages = new ArrayList<String>(); |
| for (Throwable exception : myExceptions) { |
| messages.add(exception.getMessage()); |
| } |
| AbstractVcsHelper.getInstance(myProject) |
| .showErrors(Collections.singletonList(new VcsException(messages)), SvnBundle.message("action.change.wcopy.format.task.title")); |
| } |
| } |
| |
| public void run(@NotNull final ProgressIndicator indicator) { |
| ProjectLevelVcsManager.getInstanceChecked(myProject).startBackgroundVcsOperation(); |
| indicator.setIndeterminate(true); |
| final boolean supportsChangelists = myNewFormat.supportsChangelists(); |
| if (supportsChangelists) { |
| myBeforeChangeLists = ChangeListManager.getInstance(myProject).getChangeListsCopy(); |
| } |
| |
| try { |
| for (WCInfo wcInfo : myWcInfos) { |
| File path = new File(wcInfo.getPath()); |
| if (! wcInfo.isIsWcRoot()) { |
| path = SvnUtil.getWorkingCopyRoot(path); |
| } |
| try { |
| String cleanupMessage = SvnBundle.message("action.Subversion.cleanup.progress.text", path.getAbsolutePath()); |
| String upgradeMessage = |
| SvnBundle.message("action.change.wcopy.format.task.progress.text", path.getAbsolutePath(), wcInfo.getFormat(), myNewFormat); |
| ProgressTracker handler = createUpgradeHandler(indicator, cleanupMessage, upgradeMessage); |
| |
| getFactory(path, myNewFormat).createUpgradeClient().upgrade(path, myNewFormat, handler); |
| } catch (Throwable e) { |
| myExceptions.add(e); |
| } |
| } |
| } |
| finally { |
| ProjectLevelVcsManager.getInstance(myProject).stopBackgroundVcsOperation(); |
| |
| // to map to native |
| if (supportsChangelists) { |
| SvnVcs.getInstance(myProject).processChangeLists(myBeforeChangeLists); |
| } |
| |
| ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run(); |
| } |
| } |
| |
| @NotNull |
| private ClientFactory getFactory(@NotNull File path, @NotNull WorkingCopyFormat format) throws VcsException { |
| ClientFactory factory = myVcs.getFactory(path); |
| ClientFactory otherFactory = myVcs.getOtherFactory(factory); |
| List<WorkingCopyFormat> factoryFormats = factory.createUpgradeClient().getSupportedFormats(); |
| List<WorkingCopyFormat> otherFactoryFormats = getOtherFactoryFormats(otherFactory); |
| |
| return factoryFormats.contains(format) || !otherFactoryFormats.contains(format) ? factory : otherFactory; |
| } |
| |
| public static List<WorkingCopyFormat> getOtherFactoryFormats(@NotNull ClientFactory otherFactory) { |
| List<WorkingCopyFormat> result; |
| |
| try { |
| result = otherFactory.createUpgradeClient().getSupportedFormats(); |
| } |
| catch (VcsException e) { |
| result = ContainerUtil.newArrayList(); |
| LOG.info("Failed to get upgrade formats from other factory", e); |
| } |
| |
| return result; |
| } |
| |
| private static ProgressTracker createUpgradeHandler(@NotNull final ProgressIndicator indicator, |
| @NotNull final String cleanupMessage, |
| @NotNull final String upgradeMessage) { |
| return new ProgressTracker() { |
| @Override |
| public void consume(ProgressEvent event) throws SVNException { |
| if (event.getFile() != null) { |
| if (EventAction.UPGRADED_PATH.equals(event.getAction())) { |
| indicator.setText2("Upgraded path " + VcsUtil.getPathForProgressPresentation(event.getFile())); |
| } |
| // fake event indicating cleanup start |
| if (EventAction.UPDATE_STARTED.equals(event.getAction())) { |
| indicator.setText(cleanupMessage); |
| } |
| // fake event indicating upgrade start |
| if (EventAction.UPDATE_COMPLETED.equals(event.getAction())) { |
| indicator.setText(upgradeMessage); |
| } |
| } |
| } |
| |
| @Override |
| public void checkCancelled() throws SVNCancelException { |
| indicator.checkCanceled(); |
| } |
| }; |
| } |
| } |