@Nullable private static VirtualFile findFileToPatchByComponents( ApplyPatchContext context, final String[] pathNameComponents, final int lastComponentToFind) { VirtualFile patchedDir = context.getBaseDir(); for (int i = context.getSkipTopDirs(); i < lastComponentToFind; i++) { VirtualFile nextChild; if (pathNameComponents[i].equals("..")) { nextChild = patchedDir.getParent(); } else { nextChild = patchedDir.findChild(pathNameComponents[i]); } if (nextChild == null) { if (context.isCreateDirectories()) { try { nextChild = patchedDir.createChildDirectory(null, pathNameComponents[i]); } catch (IOException e) { return null; } } else { context.registerMissingDirectory(patchedDir, pathNameComponents, i); return null; } } patchedDir = nextChild; } return patchedDir; }
private static boolean checkPackageRename( final ApplyPatchContext context, final String[] beforeNameComponents, final String[] afterNameComponents) { int changedIndex = -1; for (int i = context.getSkipTopDirs(); i < afterNameComponents.length - 1; i++) { if (!beforeNameComponents[i].equals(afterNameComponents[i])) { if (changedIndex != -1) { return true; } changedIndex = i; } } if (changedIndex == -1) return false; VirtualFile oldDir = findFileToPatchByComponents(context, beforeNameComponents, changedIndex + 1); VirtualFile newDir = findFileToPatchByComponents( context.getPrepareContext(), afterNameComponents, changedIndex + 1); if (oldDir != null && newDir == null) { context.addPendingRename(oldDir, afterNameComponents[changedIndex]); return false; } return true; }
@Nullable public static VirtualFile findPatchTarget( final ApplyPatchContext context, final String beforeName, final String afterName, final boolean isNewFile) throws IOException { VirtualFile file = null; if (beforeName != null) { file = findFileToPatchByName(context, beforeName, isNewFile); } if (file == null) { file = findFileToPatchByName(context, afterName, isNewFile); } else if (context.isAllowRename() && afterName != null && !beforeName.equals(afterName)) { String[] beforeNameComponents = beforeName.split("/"); String[] afterNameComponents = afterName.split("/"); if (!beforeNameComponents[beforeNameComponents.length - 1].equals( afterNameComponents[afterNameComponents.length - 1])) { context.registerBeforeRename(file); file.rename(FilePatch.class, afterNameComponents[afterNameComponents.length - 1]); context.addAffectedFile(file); } boolean needMove = (beforeNameComponents.length != afterNameComponents.length); if (!needMove) { needMove = checkPackageRename(context, beforeNameComponents, afterNameComponents); } if (needMove) { VirtualFile moveTarget = findFileToPatchByComponents( context, afterNameComponents, afterNameComponents.length - 1); if (moveTarget == null) { return null; } context.registerBeforeRename(file); file.move(FilePatch.class, moveTarget); context.addAffectedFile(file); } } return file; }
public Result apply( final VirtualFile fileToPatch, final ApplyPatchContext context, final Project project, FilePath pathBeforeRename, Getter<CharSequence> baseContents, CommitContext commitContext) throws IOException { if (LOG.isDebugEnabled()) { LOG.debug("apply patch called for : " + fileToPatch.getPath()); } context.addAffectedFile(getTarget(fileToPatch)); if (myPatch.isNewFile()) { applyCreate(fileToPatch, commitContext); } else if (myPatch.isDeletedFile()) { FileEditorManagerImpl.getInstance(project).closeFile(fileToPatch); fileToPatch.delete(this); } else { return applyChange(project, fileToPatch, pathBeforeRename, baseContents); } return SUCCESS; }