/* * 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.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; import java.util.regex.Pattern; import jetbrains.buildServer.util.FileUtil; import jetbrains.teamcity.Activator; import jetbrains.teamcity.core.Debug; import jetbrains.teamcity.core.Util; import org.eclipse.compare.CompareConfiguration; import org.eclipse.compare.patch.ApplyPatchOperation; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; public class ApplyPatchAction extends Action { private final IStorage myPatch; public ApplyPatchAction(IStorage patch) { super("Apply patch..."); myPatch = patch; } private class PatchParser { private String[] indexes; PatchParser parse(InputStream source) throws CoreException { try { final Pattern indexPattern = Pattern.compile("Index: "); final HashSet out = new HashSet(); BufferedReader reader = new BufferedReader(new InputStreamReader(myPatch.getContents())); String str; while ((str = reader.readLine()) != null) { if (indexPattern.matcher(str).matches()) { out.add(str.substring(indexPattern.pattern().length(), str.length()).trim()); } } indexes = out.toArray(new String[out.size()]); } catch (Exception e) { throw new CoreException(Util.createStatus(e)); } finally { FileUtil.close(source); } return this; } String[] indexes() { return indexes; } } @Override public void run() { try { // prepare for safe patching HashSet resourceToPatch = new HashSet(); for (String index : new PatchParser().parse(myPatch.getContents()).indexes()) { final IPath target = Path.fromPortableString(index); IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(target); if (member == null) { member = findInProjects(target); if (member != null) { resourceToPatch.add(member); } else { Debug.getInstance().log(Debug.DEBUG_PLATFORM, String.format("%s: Could not find member for %s", getClass().getSimpleName(), target)); } } } // TODO: check modification states of files and ask for shelving final CompareConfiguration configuration = new CompareConfiguration(); configuration.setLeftEditable(true); configuration.setProperty(CompareConfiguration.SHOW_PSEUDO_CONFLICTS, true); configuration.setProperty(CompareConfiguration.USE_OUTLINE_VIEW, true); final ApplyPatchOperation op = new ApplyPatchOperation(null, myPatch, null, configuration) { }; op.openWizard(); } catch (Exception e) { Activator.getDefault().getLog().log(Util.createStatus(e)); } super.run(); } private static IResource findInProjects(IPath target) { for (IProject prj : ResourcesPlugin.getWorkspace().getRoot().getProjects()) { final IResource member = prj.findMember(target); if (member != null) { return member; } } return null; } }