List of usage examples for org.eclipse.jgit.diff Edit Edit
public Edit(int as, int ae, int bs, int be)
From source file:com.google.gerrit.server.patch.IntraLineDiff.java
License:Apache License
private static Edit readEdit(InputStream in) throws IOException { int beginA = readVarInt32(in); int endA = readVarInt32(in); int beginB = readVarInt32(in); int endB = readVarInt32(in); return new Edit(beginA, endA, beginB, endB); }
From source file:com.google.gerrit.server.patch.IntraLineLoader.java
License:Apache License
static IntraLineDiff compute(Text aText, Text bText, List<Edit> edits) throws Exception { combineLineEdits(edits, aText, bText); for (int i = 0; i < edits.size(); i++) { Edit e = edits.get(i);/*from w w w . j a va2 s. co m*/ if (e.getType() == Edit.Type.REPLACE) { CharText a = new CharText(aText, e.getBeginA(), e.getEndA()); CharText b = new CharText(bText, e.getBeginB(), e.getEndB()); CharTextComparator cmp = new CharTextComparator(); List<Edit> wordEdits = MyersDiff.INSTANCE.diff(cmp, a, b); // Combine edits that are really close together. If they are // just a few characters apart we tend to get better results // by joining them together and taking the whole span. // for (int j = 0; j < wordEdits.size() - 1;) { Edit c = wordEdits.get(j); Edit n = wordEdits.get(j + 1); if (n.getBeginA() - c.getEndA() <= 5 || n.getBeginB() - c.getEndB() <= 5) { int ab = c.getBeginA(); int ae = n.getEndA(); int bb = c.getBeginB(); int be = n.getEndB(); if (canCoalesce(a, c.getEndA(), n.getBeginA()) && canCoalesce(b, c.getEndB(), n.getBeginB())) { wordEdits.set(j, new Edit(ab, ae, bb, be)); wordEdits.remove(j + 1); continue; } } j++; } // Apply some simple rules to fix up some of the edits. Our // logic above, along with our per-character difference tends // to produce some crazy stuff. // for (int j = 0; j < wordEdits.size(); j++) { Edit c = wordEdits.get(j); int ab = c.getBeginA(); int ae = c.getEndA(); int bb = c.getBeginB(); int be = c.getEndB(); // Sometimes the diff generator produces an INSERT or DELETE // right up against a REPLACE, but we only find this after // we've also played some shifting games on the prior edit. // If that happened to us, coalesce them together so we can // correct this mess for the user. If we don't we wind up // with silly stuff like "es" -> "es = Addresses". // if (1 < j) { Edit p = wordEdits.get(j - 1); if (p.getEndA() == ab || p.getEndB() == bb) { if (p.getEndA() == ab && p.getBeginA() < p.getEndA()) { ab = p.getBeginA(); } if (p.getEndB() == bb && p.getBeginB() < p.getEndB()) { bb = p.getBeginB(); } wordEdits.remove(--j); } } // We sometimes collapsed an edit together in a strange way, // such that the edges of each text is identical. Fix by // by dropping out that incorrectly replaced region. // while (ab < ae && bb < be && cmp.equals(a, ab, b, bb)) { ab++; bb++; } while (ab < ae && bb < be && cmp.equals(a, ae - 1, b, be - 1)) { ae--; be--; } // The leading part of an edit and its trailing part in the same // text might be identical. Slide down that edit and use the tail // rather than the leading bit. If however the edit is only on a // whitespace block try to shift it to the left margin, assuming // that it is an indentation change. // boolean aShift = true; if (ab < ae && isOnlyWhitespace(a, ab, ae)) { int lf = findLF(wordEdits, j, a, ab); if (lf < ab && a.charAt(lf) == '\n') { int nb = lf + 1; int p = 0; while (p < ae - ab) { if (cmp.equals(a, ab + p, a, ab + p)) { p++; } else { break; } } if (p == ae - ab) { ab = nb; ae = nb + p; aShift = false; } } } if (aShift) { while (0 < ab && ab < ae && a.charAt(ab - 1) != '\n' && cmp.equals(a, ab - 1, a, ae - 1)) { ab--; ae--; } if (!a.isLineStart(ab) || !a.contains(ab, ae, '\n')) { while (ab < ae && ae < a.size() && cmp.equals(a, ab, a, ae)) { ab++; ae++; if (a.charAt(ae - 1) == '\n') { break; } } } } boolean bShift = true; if (bb < be && isOnlyWhitespace(b, bb, be)) { int lf = findLF(wordEdits, j, b, bb); if (lf < bb && b.charAt(lf) == '\n') { int nb = lf + 1; int p = 0; while (p < be - bb) { if (cmp.equals(b, bb + p, b, bb + p)) { p++; } else { break; } } if (p == be - bb) { bb = nb; be = nb + p; bShift = false; } } } if (bShift) { while (0 < bb && bb < be && b.charAt(bb - 1) != '\n' && cmp.equals(b, bb - 1, b, be - 1)) { bb--; be--; } if (!b.isLineStart(bb) || !b.contains(bb, be, '\n')) { while (bb < be && be < b.size() && cmp.equals(b, bb, b, be)) { bb++; be++; if (b.charAt(be - 1) == '\n') { break; } } } } // If most of a line was modified except the LF was common, make // the LF part of the modification region. This is easier to read. // if (ab < ae // && (ab == 0 || a.charAt(ab - 1) == '\n') // && ae < a.size() && a.charAt(ae - 1) != '\n' && a.charAt(ae) == '\n') { ae++; } if (bb < be // && (bb == 0 || b.charAt(bb - 1) == '\n') // && be < b.size() && b.charAt(be - 1) != '\n' && b.charAt(be) == '\n') { be++; } wordEdits.set(j, new Edit(ab, ae, bb, be)); } edits.set(i, new ReplaceEdit(e, wordEdits)); } } return new IntraLineDiff(edits); }
From source file:com.google.gerrit.server.patch.IntraLineLoader.java
License:Apache License
private static void combineLineEdits(List<Edit> edits, Text a, Text b) { for (int j = 0; j < edits.size() - 1;) { Edit c = edits.get(j);// w w w .ja va 2 s . c o m Edit n = edits.get(j + 1); // Combine edits that are really close together. Right now our rule // is, coalesce two line edits which are only one line apart if that // common context line is either a "pointless line", or is identical // on both sides and starts a new block of code. These are mostly // block reindents to add or remove control flow operators. // final int ad = n.getBeginA() - c.getEndA(); final int bd = n.getBeginB() - c.getEndB(); if ((1 <= ad && isBlankLineGap(a, c.getEndA(), n.getBeginA())) || (1 <= bd && isBlankLineGap(b, c.getEndB(), n.getBeginB())) || (ad == 1 && bd == 1 && isControlBlockStart(a, c.getEndA()))) { int ab = c.getBeginA(); int ae = n.getEndA(); int bb = c.getBeginB(); int be = n.getEndB(); edits.set(j, new Edit(ab, ae, bb, be)); edits.remove(j + 1); continue; } j++; } }
From source file:com.google.gerrit.server.patch.IntraLineLoaderTest.java
License:Apache License
private static List<Edit> intraline(String a, String b) throws Exception { return intraline(a, b, new Edit(0, countLines(a), 0, countLines(b))); }
From source file:com.google.gerrit.server.patch.IntraLineLoaderTest.java
License:Apache License
private static List<Edit> wordEdit(int as, int ae, int bs, int be) { return EditList.singleton(new Edit(as, ae, bs, be)); }
From source file:com.google.gerrit.server.patch.PatchListEntry.java
License:Apache License
static PatchListEntry readFrom(final InputStream in) throws IOException { final ChangeType changeType = readEnum(in, ChangeType.values()); final PatchType patchType = readEnum(in, PatchType.values()); final String oldName = readString(in); final String newName = readString(in); final byte[] hdr = readBytes(in); final int ins = readVarInt32(in); final int del = readVarInt32(in); final int editCount = readVarInt32(in); final Edit[] editArray = new Edit[editCount]; for (int i = 0; i < editCount; i++) { int beginA = readVarInt32(in); int endA = readVarInt32(in); int beginB = readVarInt32(in); int endB = readVarInt32(in); editArray[i] = new Edit(beginA, endA, beginB, endB); }//from w ww.ja v a 2s .c o m return new PatchListEntry(changeType, patchType, oldName, newName, hdr, toList(editArray), ins, del); }
From source file:org.eclipse.mylyn.internal.gerrit.core.client.JSonSupport.java
License:Open Source License
public JSonSupport() { TypeToken<Map<Id, PatchSetApproval>> approvalMapType = new TypeToken<Map<ApprovalCategory.Id, PatchSetApproval>>() { };// ww w . j a v a 2 s. c o m ExclusionStrategy exclustionStrategy = new ExclusionStrategy() { public boolean shouldSkipField(FieldAttributes f) { // commentLinks requires instantiation of com.google.gwtexpui.safehtml.client.RegexFindReplace which is not on classpath if (f.getDeclaredClass() == List.class && f.getName().equals("commentLinks") //$NON-NLS-1$ && f.getDeclaringClass() == GerritConfig.class) { return true; } if (f.getDeclaredClass() == Map.class && f.getName().equals("given")) { //$NON-NLS-1$ //return true; } // GSon 2.1 fails to deserialize the SubmitType enum if (f.getDeclaringClass() == Project.class && f.getName().equals("submitType")) { //$NON-NLS-1$ return true; } return false; } public boolean shouldSkipClass(Class<?> clazz) { return false; } }; gson = JsonServlet.defaultGsonBuilder() .registerTypeAdapter(JSonResponse.class, new JSonResponseDeserializer()) .registerTypeAdapter(Edit.class, new JsonDeserializer<Edit>() { public Edit deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonArray()) { JsonArray array = json.getAsJsonArray(); if (array.size() == 4) { return new Edit(array.get(0).getAsInt(), array.get(1).getAsInt(), array.get(2).getAsInt(), array.get(3).getAsInt()); } } return new Edit(0, 0); } }) // ignore GerritForge specific AuthType "TEAMFORGE" which is unknown to Gerrit .registerTypeAdapter(AuthType.class, new JsonDeserializer<AuthType>() { @Override public AuthType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String jsonString = json.getAsString(); if (jsonString != null) { try { return AuthType.valueOf(jsonString); } catch (IllegalArgumentException e) { // ignore the error since the connector does not make use of AuthType //GerritCorePlugin.logWarning("Ignoring unkown authentication type: " + jsonString, e); } } return null; } }) .registerTypeAdapter(approvalMapType.getType(), new JsonDeserializer<Map<Id, PatchSetApproval>>() { @Override public Map<Id, PatchSetApproval> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // Gerrit 2.2: the type of PatchSetPublishDetail.given changed from a map to a list Map<Id, PatchSetApproval> map = new HashMap<ApprovalCategory.Id, PatchSetApproval>(); if (json.isJsonArray()) { JsonArray array = json.getAsJsonArray(); for (Iterator<JsonElement> it = array.iterator(); it.hasNext();) { JsonElement element = it.next(); Id key = context.deserialize(element, Id.class); if (key.get() != null) { // Gerrit < 2.1.x: json is map element = it.next(); } PatchSetApproval value = context.deserialize(element, PatchSetApproval.class); if (key.get() == null) { // Gerrit 2.2: json is a list, deduct key from value key = value.getCategoryId(); } map.put(key, value); } } return map; } }).setExclusionStrategies(exclustionStrategy).create(); }