/* * Copyright 2000-2020 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 jetbrains.teamcity.ui.actions; import java.io.File; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import jetbrains.buildServer.delayedCommit.RemoteRunSessionData; import jetbrains.teamcity.Activator; import jetbrains.teamcity.Constants; import jetbrains.teamcity.SharedImages; import jetbrains.teamcity.core.Util; import jetbrains.teamcity.core.remote.*; import jetbrains.teamcity.ui.UIUtil; import jetbrains.teamcity.ui.views.ChangesView; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.TeamException; import org.eclipse.ui.PlatformUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ApplyChangesToLocal extends Action implements ISelectionChangedListener { private final ChangesView myChangesView; private long myChangeId; public ApplyChangesToLocal(final ChangesView changesView) { super(Messages.getString("ApplyChangesToLocal.action.name"), SharedImages.getImageDescriptorByPath(SharedImages.CHECKOUT_ACTION)); //$NON-NLS-1$ myChangesView = changesView; } @Override public void run() { try { final ITCRemoterunContext context = RemoteRunManager2.load(myChangeId); if (context == null) { Activator.getDefault().getLog().log(Util.createStatus(IStatus.WARNING, String.format("Could not found ITCRemoterunContext for \"%s\" change", myChangeId))); //$NON-NLS-1$ return; } Display.getDefault().asyncExec(new Runnable() { public void run() { final IRemoteRunSessionData sessionData = context.getSessionData(); final int countOfChanges = sessionData.getPaths().size(); if (MessageDialog.openQuestion(null, getText(), MessageFormat.format(Messages.getString("ApplyChangesToLocal.confirmation.text"), countOfChanges))) { //$NON-NLS-1$ final Job job = new Job(getText()) { @Override protected IStatus run(IProgressMonitor monitor) { try { if (isFilesReadyToReplace(sessionData, monitor)) { final LocalPatcher patcher = PatcherHelper.createPatcher(new File(Constants.EMPTY_STRING).getAbsoluteFile(), sessionData); patcher.applyPatch(); refreshEditors(sessionData, monitor); } } catch (Exception e) { return Util.createStatus(e); } return Status.OK_STATUS; } }; PlatformUI.getWorkbench().getProgressService().showInDialog(null, job); job.schedule(); } } }); } catch (Exception e) { Activator.getDefault().getLog().log(Util.createStatus(IStatus.ERROR, e.getMessage())); } } protected boolean isFilesReadyToReplace(final IRemoteRunSessionData sessionData, final IProgressMonitor monitor) throws TeamException { final HashSet files = new HashSet(); try { files.addAll(Util.findFiles(sessionData.getPaths(), monitor)); return UIUtil.Resources.makeFilesWritable(monitor, files); } catch (CoreException e) { throw new TeamException(e.getStatus()); } } private void refreshEditors(final IRemoteRunSessionData sessionData, final IProgressMonitor monitor) throws CoreException { // refresh editors if required final Collection paths = sessionData.getPaths(); for (final IFile file : Util.findFiles(paths.toArray(new String[paths.size()]), monitor)) { file.refreshLocal(IResource.DEPTH_ZERO, monitor); } } public void selectionChanged(SelectionChangedEvent event) { final ISelection selection = myChangesView.getSite().getSelectionProvider().getSelection(); if (selection instanceof StructuredSelection && !selection.isEmpty()) { final Object[] elements = ((StructuredSelection) selection).toArray(); if (elements.length == 1 && elements[0] instanceof IAdaptable) { final RemoteRunSessionData sessionData = (RemoteRunSessionData) ((IAdaptable) elements[0]).getAdapter(RemoteRunSessionData.class); if (sessionData != null) { myChangeId = sessionData.getChangeId(); setEnabled(true); return; } } } setEnabled(false); } static class ValidationDataHolder { private final IProject myProject; private final HashSet myResources = new HashSet(); IProject getProject() { return myProject; } IFile[] getResources() { return myResources.toArray(new IFile[myResources.size()]); } void addResource(final IFile file) { myResources.add(file); } ValidationDataHolder(@NotNull final IProject project) { myProject = project; } ValidationDataHolder(@NotNull final IProject project, @Nullable final IFile[] resources) { this(project); if (resources != null) { myResources.addAll(Arrays.asList(resources)); } } } }