1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.blame.internal

File DefaultAnnotatedContent.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

22
42
10
2
179
113
22
0.52
4.2
5
2.2

Classes

Class Line # Actions
DefaultAnnotatedContent 42 38 0% 19 3
0.9552238695.5%
DefaultAnnotatedContent.AnnotatedContentIterator 65 4 0% 3 2
0.7142857371.4%
 

Contributing tests

This file is covered by 1 test. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20   
21    package org.xwiki.blame.internal;
22   
23    import java.util.ArrayList;
24    import java.util.Iterator;
25    import java.util.List;
26   
27    import org.xwiki.blame.AnnotatedContent;
28    import org.xwiki.blame.AnnotatedElement;
29   
30    import difflib.Chunk;
31    import difflib.Delta;
32    import difflib.DiffUtils;
33   
34    /**
35    * Hold content during blame analysis and provides actual results.
36    *
37    * @param <R> type of the revision object that old metadata about the revision.
38    * @param <E> type of the element to annotate (ie: String holding a line).
39    * @version $Id: f4375b8aea434f0c91a5858723e5c20f4a8cab86 $
40    * @since 6.2M2
41    */
 
42    public class DefaultAnnotatedContent<R, E> implements AnnotatedContent<R, E>
43    {
44    private final List<R> sourceRevisions;
45    private final List<E> initialContent;
46    private final List<E> currentRevisionContent;
47    private R currentRevision;
48    private final List<Integer> elementList;
49    private final int size;
50   
 
51  1 toggle DefaultAnnotatedContent(R revision, List<E> initialContent)
52    {
53  1 this.size = initialContent.size();
54  1 this.sourceRevisions = new ArrayList<R>(this.size);
55  1 this.initialContent = initialContent;
56  1 this.currentRevisionContent = new ArrayList<E>(initialContent);
57  1 this.currentRevision = revision;
58  1 this.elementList = new ArrayList<>(this.size);
59  6 for (int i = 0; i < size; i++) {
60  5 this.sourceRevisions.add(null);
61  5 this.elementList.add(i);
62    }
63    }
64   
 
65    private class AnnotatedContentIterator implements Iterator<AnnotatedElement<R, E>>
66    {
67    private int index = -1;
68   
 
69  5 toggle @Override
70    public boolean hasNext()
71    {
72  5 return index < (size - 1);
73    }
74   
 
75  5 toggle @Override
76    public AnnotatedElement<R, E> next()
77    {
78  5 index += 1;
79  5 return new DefaultAnnotatedElement<R, E>(sourceRevisions.get(index), initialContent.get(index));
80    }
81   
 
82  0 toggle @Override
83    public void remove()
84    {
85  0 throw new UnsupportedOperationException();
86    }
87    }
88   
 
89  1 toggle @Override
90    public Iterator<AnnotatedElement<R, E>> iterator()
91    {
92  1 return new AnnotatedContentIterator();
93    }
94   
 
95  4 toggle @Override
96    public R getOldestRevision()
97    {
98  4 return currentRevision;
99    }
100   
 
101  4 toggle @Override
102    public boolean isEntirelyAnnotated()
103    {
104  11 for (int i = 0; i < this.size; i++) {
105  10 if (this.sourceRevisions.get(i) == null) {
106  3 return false;
107    }
108    }
109  1 return true;
110    }
111   
112    /**
113    * Resolve revision of line to current revision based on given previous content, and prepare for next analysis.
114    *
115    * @param revision the revision of the content provided.
116    * @param previous the content in a previous revision.
117    */
 
118  3 toggle void analyseRevision(R revision, List<E> previous)
119    {
120  3 if (currentRevision == null) {
121  0 return;
122    }
123   
124  3 if (previous == null || previous.isEmpty()) {
125  1 resolveRemainingToCurrent();
126    } else {
127  2 resolveToCurrent(DiffUtils.diff(currentRevisionContent, previous).getDeltas());
128  2 assert currentRevisionContent.equals(previous) : "Patch application failed";
129    }
130   
131  3 currentRevision = revision;
132    }
133   
134    /**
135    * Resolve revision of line to current revision based on given previous content.
136    *
137    * Thanks to Michael Schierl <schierlm%40gmx.de> for sharing this code on StackOverflow.
138    *
139    * @param deltas the delta to apply to current content to move to previous revision.
140    */
 
141  2 toggle private void resolveToCurrent(List<Delta<E>> deltas)
142    {
143  2 int lineOffset = 0;
144   
145  2 for (Delta<E> d : deltas) {
146  3 Chunk<E> original = d.getOriginal();
147  3 Chunk<E> revised = d.getRevised();
148   
149  3 int pos = original.getPosition() + lineOffset;
150    // delete lines
151  8 for (int i = 0; i < original.size(); i++) {
152  5 int origLine = elementList.remove(pos);
153  5 currentRevisionContent.remove(pos);
154  5 if (origLine != -1) {
155  4 sourceRevisions.set(origLine, currentRevision);
156    }
157    }
158   
159  6 for (int i = 0; i < revised.size(); i++) {
160  3 currentRevisionContent.add(pos + i, revised.getLines().get(i));
161  3 elementList.add(pos + i, -1);
162    }
163   
164  3 lineOffset += revised.size() - original.size();
165    }
166    }
167   
168    /**
169    * Resolve all line remaining without revision to current.
170    */
 
171  1 toggle private void resolveRemainingToCurrent()
172    {
173  6 for (int i = 0; i < this.size; i++) {
174  5 if (sourceRevisions.get(i) == null) {
175  1 sourceRevisions.set(i, currentRevision);
176    }
177    }
178    }
179    }