-
Notifications
You must be signed in to change notification settings - Fork 128
/
InlineHintService.java
220 lines (198 loc) · 8.94 KB
/
InlineHintService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package org.jboss.windup.reporting.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import org.apache.tools.ant.taskdefs.Length.FileMode;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.graph.model.ProjectModel;
import org.jboss.windup.graph.model.WindupVertexFrame;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.graph.service.GraphService;
import org.jboss.windup.graph.traversal.ProjectModelTraversal;
import org.jboss.windup.reporting.TagUtil;
import org.jboss.windup.reporting.model.EffortReportModel;
import org.jboss.windup.reporting.model.InlineHintModel;
import org.jboss.windup.reporting.model.Severity;
import org.jboss.windup.rules.files.model.FileReferenceModel;
import com.thinkaurelius.titan.core.attribute.Text;
import com.tinkerpop.blueprints.Compare;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.frames.structures.FramedVertexIterable;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.PipeFunction;
import javax.annotation.Nullable;
import org.jboss.windup.reporting.model.ClassificationModel;
/**
* This provides helper functions for finding and creating {@link InlineHintModel} instances within the graph.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class InlineHintService extends GraphService<InlineHintModel>
{
public InlineHintService(GraphContext context)
{
super(context, InlineHintModel.class);
}
/**
* Gets all {@link InlineHintModel} instances that are directly associated with the given {@link FileReferenceModel}
*/
public Iterable<InlineHintModel> getHintsForFileReference(FileReferenceModel reference)
{
GremlinPipeline<Vertex, Vertex> inlineHintPipeline = new GremlinPipeline<>(reference.asVertex());
inlineHintPipeline.in(InlineHintModel.FILE_LOCATION_REFERENCE);
inlineHintPipeline.has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, InlineHintModel.TYPE);
return new FramedVertexIterable<>(getGraphContext().getFramed(), inlineHintPipeline, InlineHintModel.class);
}
/**
* Gets all {@link InlineHintModel} instances that are directly associated with the given {@link FileModel}
*/
public Iterable<InlineHintModel> getHintsForFile(FileModel file)
{
GremlinPipeline<Vertex, Vertex> inlineHintPipeline = new GremlinPipeline<>(file.asVertex());
inlineHintPipeline.in(FileReferenceModel.FILE_MODEL);
inlineHintPipeline.has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, InlineHintModel.TYPE);
return new FramedVertexIterable<>(getGraphContext().getFramed(), inlineHintPipeline, InlineHintModel.class);
}
/**
* Returns the total effort points in all of the {@link InlineHintModel} instances associated with the provided {@link FileModel}.
*/
public int getMigrationEffortPoints(FileModel fileModel)
{
GremlinPipeline<Vertex, Vertex> inlineHintPipeline = new GremlinPipeline<>(fileModel.asVertex());
inlineHintPipeline.in(InlineHintModel.FILE_MODEL);
inlineHintPipeline.has(EffortReportModel.EFFORT, Compare.GREATER_THAN, 0);
inlineHintPipeline.has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, InlineHintModel.TYPE);
int hintEffort = 0;
for (Vertex v : inlineHintPipeline)
{
hintEffort += (Integer) v.getProperty(InlineHintModel.EFFORT);
}
return hintEffort;
}
private Collection<Vertex> getProjectAndChildren(ProjectModel projectModel)
{
ArrayList<Vertex> result = new ArrayList<>();
result.add(projectModel.asVertex());
for (ProjectModel child : projectModel.getChildProjects())
{
result.addAll(getProjectAndChildren(child));
}
return result;
}
/**
* Returns all hints for the given {@link ProjectModel}. If recursive is set, then this will recurse into
* child projects as well.
*/
public Iterable<InlineHintModel> getHintsForProject(ProjectModel projectModel, boolean recursive)
{
final Iterable<Vertex> initialVertices;
if (recursive)
{
initialVertices = getProjectAndChildren(projectModel);
}
else
{
initialVertices = Collections.singletonList(projectModel.asVertex());
}
return getInlineHintModels(initialVertices);
}
public Iterable<InlineHintModel> getHintsForProjects(Iterable<ProjectModel> projectModels)
{
Iterable<Vertex> projectVertexIterable = Iterables.transform(projectModels, new Function<ProjectModel, Vertex>()
{
@Override
public Vertex apply(ProjectModel input)
{
return input.asVertex();
}
});
return getInlineHintModels(projectVertexIterable);
}
private Iterable<InlineHintModel> getInlineHintModels(Iterable<Vertex> initialProjectVertices) {
GremlinPipeline<Vertex, Vertex> inlineHintPipeline = new GremlinPipeline<>(initialProjectVertices);
inlineHintPipeline.out(ProjectModel.PROJECT_MODEL_TO_FILE);
inlineHintPipeline.in(InlineHintModel.FILE_MODEL).has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, InlineHintModel.TYPE);
Set<InlineHintModel> results = new LinkedHashSet<>();
for (Vertex v : inlineHintPipeline)
{
results.add(frame(v));
}
return results;
}
/**
* <p>
* Returns the total effort points in all of the {@link InlineHintModel}s
* associated with the {@link FileMode} instances in the given {@link ProjectModelTraversal}.
* </p>
* <p>
* If set to recursive, then also include the effort points from child projects.
* </p>
* <p>
* The result is a Map, the key contains the effort level and the value contains the number of incidents.
* </p>
*/
public Map<Integer, Integer> getMigrationEffortByPoints(
ProjectModelTraversal traversal, Set<String> includeTags, Set<String> excludeTags, boolean recursive, boolean includeZero)
{
MapSumEffortAccumulatorFunction<Integer> accumulator = new MapSumEffortAccumulatorFunction(){
public Object vertexToKey(Vertex effortReportVertex) {
Integer migrationEffort = effortReportVertex.getProperty(EffortReportModel.EFFORT);
return migrationEffort;
}
};
getMigrationEffortDetails(traversal, includeTags, excludeTags, recursive, includeZero, accumulator);
return accumulator.getResults();
}
/**
* Returns the total incidents in all of the {@link InlineHintModel}s associated with the files in this project by severity.
*/
public Map<Severity, Integer> getMigrationEffortBySeverity(ProjectModelTraversal traversal, Set<String> includeTags, Set<String> excludeTags,
boolean recursive)
{
MapSumEffortAccumulatorFunction<Severity> accumulator = new MapSumEffortAccumulatorFunction(){
public Severity vertexToKey(Vertex effortReportVertex) {
return frame(effortReportVertex).getSeverity();
}
};
this.getMigrationEffortDetails(traversal, includeTags, excludeTags, recursive, true, accumulator);
return accumulator.getResults();
}
private void getMigrationEffortDetails(ProjectModelTraversal traversal, Set<String> includeTags, Set<String> excludeTags, boolean recursive,
boolean includeZero, EffortAccumulatorFunction accumulatorFunction)
{
final Set<Vertex> initialVertices = traversal.getAllProjectsAsVertices(recursive);
GremlinPipeline<Vertex, Vertex> pipeline = new GremlinPipeline<>(this.getGraphContext().getGraph());
pipeline.V();
// If the multivalue index is not 1st, then it doesn't work - https://github.com/thinkaurelius/titan/issues/403
if (!includeZero)
{
pipeline.has(EffortReportModel.EFFORT, Compare.GREATER_THAN, 0);
pipeline.has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, InlineHintModel.TYPE);
}
else
{
pipeline.has(WindupVertexFrame.TYPE_PROP, InlineHintModel.TYPE);
}
pipeline.as("hint");
pipeline.out(InlineHintModel.FILE_MODEL);
pipeline.in(ProjectModel.PROJECT_MODEL_TO_FILE);
pipeline.filter(new SetMembersFilter(initialVertices));
pipeline.back("hint");
boolean checkTags = !includeTags.isEmpty() || !excludeTags.isEmpty();
for (Vertex v : pipeline)
{
// only check tags if we have some passed in
if (checkTags && !frame(v).matchesTags(includeTags, excludeTags))
continue;
accumulatorFunction.accumulate(v);
}
}
}