63 /**
64 * Comparator for ModuleElements, simply compares the fully qualified names
65 * @return a Comparator
66 */
67 public Comparator<Element> makeModuleComparator() {
68 if (moduleComparator == null) {
69 moduleComparator = new ElementComparator() {
70 @Override
71 public int compare(Element mod1, Element mod2) {
72 return compareFullyQualifiedNames(mod1, mod2);
73 }
74 };
75 }
76 return moduleComparator;
77 }
78
79 private Comparator<Element> allClassesComparator = null;
80
81 /**
82 * Returns a Comparator for all classes, compares the simple names of
83 * TypeElement, if equal then the fully qualified names.
84 *
85 * @return Comparator
86 */
87 public Comparator<Element> makeAllClassesComparator() {
88 if (allClassesComparator == null) {
89 allClassesComparator = new ElementComparator() {
90 @Override
91 public int compare(Element e1, Element e2) {
92 int result = compareNames(e1, e2);
93 if (result == 0)
94 result = compareFullyQualifiedNames(e1, e2);
95
96 return result;
97 }
98 };
99 }
100 return allClassesComparator;
101 }
102
103 private Comparator<Element> packageComparator = null;
104
105 /**
106 * Returns a Comparator for packages, by comparing the fully qualified names.
107 *
108 * @return a Comparator
109 */
110 public Comparator<Element> makePackageComparator() {
111 if (packageComparator == null) {
112 packageComparator = new ElementComparator() {
113 @Override
114 public int compare(Element pkg1, Element pkg2) {
115 return compareFullyQualifiedNames(pkg1, pkg2);
116 }
117 };
118 }
119 return packageComparator;
120 }
121
122 private Comparator<Element> deprecatedComparator = null;
123
124 /**
125 * Returns a Comparator for deprecated items listed on deprecated list page, by comparing the
126 * fully qualified names.
127 *
128 * @return a Comparator
129 */
130 public Comparator<Element> makeDeprecatedComparator() {
131 if (deprecatedComparator == null) {
132 deprecatedComparator = new ElementComparator() {
133 @Override
134 public int compare(Element e1, Element e2) {
135 return compareFullyQualifiedNames(e1, e2);
136 }
137 };
138 }
139 return deprecatedComparator;
140 }
141
142 private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
143
144 /**
145 * Returns a Comparator for SerialFieldTree.
146 * @return a Comparator
147 */
148 public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
149 if (serialFieldTreeComparator == null) {
150 serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> {
151 String s1 = o1.getName().toString();
152 String s2 = o2.getName().toString();
153 return s1.compareTo(s2);
154 };
155 }
194 return result;
195 return compareElementKinds(o1, o2);
196 }
197 };
198 }
199 return overrideUseComparator;
200 }
201
202 private Comparator<Element> indexUseComparator = null;
203
204 /**
205 * Returns an {@code Element} Comparator for index file presentations, and are sorted as follows.
206 * If comparing modules and/or packages then simply compare the qualified names,
207 * if comparing a module or a package with a type/member then compare the
208 * FullyQualifiedName of the module or a package with the SimpleName of the entity,
209 * otherwise:
210 * 1. compare the ElementKind ex: Module, Package, Interface etc.
211 * 2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
212 * a case insensitive comparison of parameter the type signatures
213 * 2b. if equal, case sensitive comparison of the type signatures
214 * 3. finally, if equal, compare the FQNs of the entities
215 * @return an element comparator for index file use
216 */
217 public Comparator<Element> makeIndexElementComparator() {
218 if (indexUseComparator == null) {
219 indexUseComparator = new ElementComparator() {
220 /**
221 * Compares two elements.
222 *
223 * @param e1 - an element.
224 * @param e2 - an element.
225 * @return a negative integer, zero, or a positive integer as the first
226 * argument is less than, equal to, or greater than the second.
227 */
228 @Override
229 public int compare(Element e1, Element e2) {
230 int result;
231 // first, compare names as appropriate
232 if ((utils.isModule(e1) || utils.isPackage(e1)) && (utils.isModule(e2) || utils.isPackage(e2))) {
233 result = compareFullyQualifiedNames(e1, e2);
234 } else if (utils.isModule(e1) || utils.isPackage(e1)) {
244 // if names are the same, compare element kinds
245 result = compareElementKinds(e1, e2);
246 if (result != 0) {
247 return result;
248 }
249 // if element kinds are the same, and are methods,
250 // compare the method parameters
251 if (hasParameters(e1)) {
252 List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
253 List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
254 result = compareParameters(false, parameters1, parameters2);
255 if (result != 0) {
256 return result;
257 }
258 result = compareParameters(true, parameters1, parameters2);
259 if (result != 0) {
260 return result;
261 }
262 }
263 // else fall back on fully qualified names
264 return compareFullyQualifiedNames(e1, e2);
265 }
266 };
267 }
268 return indexUseComparator;
269 }
270
271 /**
272 * Returns a comparator for the {@code IndexItem}s in the index page. This is a composite
273 * comparator that must be able to compare all kinds {@code Element}s as well as
274 * {@code SearchIndexItem}s.
275 *
276 * @return a comparator for index page items.
277 */
278 public Comparator<IndexItem> makeIndexComparator(boolean classesOnly) {
279 Comparator<Element> elementComparator = classesOnly
280 ? makeAllClassesComparator()
281 : makeIndexElementComparator();
282 Comparator<SearchIndexItem> searchTagComparator =
283 makeGenericSearchIndexComparator();
284
328 */
329 public Comparator<TypeMirror> makeTypeMirrorIndexUseComparator() {
330 if (typeMirrorIndexUseComparator == null) {
331 typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> {
332 int result = utils.compareStrings(utils.getTypeName(t1, false), utils.getTypeName(t2, false));
333 if (result != 0)
334 return result;
335 return utils.compareStrings(utils.getQualifiedTypeName(t1), utils.getQualifiedTypeName(t2));
336 };
337 }
338 return typeMirrorIndexUseComparator;
339 }
340
341 private Comparator<Element> classUseComparator = null;
342
343 /**
344 * Comparator for ClassUse presentations, and sorts as follows:
345 * 1. member names
346 * 2. then fully qualified member names
347 * 3. then parameter types if applicable
348 * 4. finally the element kinds ie. package, class, interface etc.
349 * @return a comparator to sort classes and members for class use
350 */
351 public Comparator<Element> makeClassUseComparator() {
352 if (classUseComparator == null) {
353 classUseComparator = new ElementComparator() {
354 /**
355 * Compares two Elements.
356 *
357 * @param e1 - an element.
358 * @param e2 - an element.
359 * @return a negative integer, zero, or a positive integer as the first
360 * argument is less than, equal to, or greater than the second.
361 */
362 @Override
363 public int compare(Element e1, Element e2) {
364 int result = compareNames(e1, e2);
365 if (result != 0) {
366 return result;
367 }
368 result = compareFullyQualifiedNames(e1, e2);
369 if (result != 0) {
370 return result;
371 }
372 if (hasParameters(e1) && hasParameters(e2)) {
373 List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
374 List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
375 result = compareParameters(false, parameters1, parameters2);
376 if (result != 0) {
377 return result;
378 }
379 result = compareParameters(true, parameters1, parameters2);
380 }
381 if (result != 0) {
382 return result;
383 }
384 return compareElementKinds(e1, e2);
385 }
386 };
387 }
388 return classUseComparator;
389 }
390
391 /**
392 * A general purpose comparator to sort Element entities, basically provides the building blocks
393 * for creating specific comparators for an use-case.
394 */
395 private abstract class ElementComparator implements Comparator<Element> {
396 public ElementComparator() { }
397
398 /**
399 * compares two parameter arrays by first comparing the length of the arrays, and
400 * then each Type of the parameter in the array.
401 * @param params1 the first parameter array.
402 * @param params2 the first parameter array.
403 * @return a negative integer, zero, or a positive integer as the first
404 * argument is less than, equal to, or greater than the second.
449 * argument is less than, equal to, or greater than the second.
450 */
451 protected int compareNames(Element e1, Element e2) {
452 return utils.compareStrings(utils.getSimpleName(e1), utils.getSimpleName(e2));
453 }
454
455 /**
456 * Compares the fully qualified names of the entities
457 * @param e1 the first Element.
458 * @param e2 the first Element.
459 * @return a negative integer, zero, or a positive integer as the first
460 * argument is less than, equal to, or greater than the second.
461 */
462 protected int compareFullyQualifiedNames(Element e1, Element e2) {
463 // add simplename to be compatible
464 String thisElement = getFullyQualifiedName(e1);
465 String thatElement = getFullyQualifiedName(e2);
466 return utils.compareStrings(thisElement, thatElement);
467 }
468
469 protected int compareElementKinds(Element e1, Element e2) {
470 return Integer.compare(getKindIndex(e1), getKindIndex(e2));
471 }
472
473 private int getKindIndex(Element e) {
474 switch (e.getKind()) {
475 case MODULE: return 0;
476 case PACKAGE: return 1;
477 case CLASS: return 2;
478 case ENUM: return 3;
479 case ENUM_CONSTANT: return 4;
480 case RECORD: return 5;
481 case INTERFACE: return 6;
482 case ANNOTATION_TYPE: return 7;
483 case FIELD: return 8;
484 case CONSTRUCTOR: return 9;
485 case METHOD: return 10;
486 default: throw new IllegalArgumentException(e.getKind().toString());
487 }
488 }
|
63 /**
64 * Comparator for ModuleElements, simply compares the fully qualified names
65 * @return a Comparator
66 */
67 public Comparator<Element> makeModuleComparator() {
68 if (moduleComparator == null) {
69 moduleComparator = new ElementComparator() {
70 @Override
71 public int compare(Element mod1, Element mod2) {
72 return compareFullyQualifiedNames(mod1, mod2);
73 }
74 };
75 }
76 return moduleComparator;
77 }
78
79 private Comparator<Element> allClassesComparator = null;
80
81 /**
82 * Returns a Comparator for all classes, compares the simple names of
83 * TypeElement, if equal then the fully qualified names, and if equal again
84 * the names of the enclosing modules.
85 *
86 * @return Comparator
87 */
88 public Comparator<Element> makeAllClassesComparator() {
89 if (allClassesComparator == null) {
90 allClassesComparator = new ElementComparator() {
91 @Override
92 public int compare(Element e1, Element e2) {
93 int result = compareNames(e1, e2);
94 if (result == 0)
95 result = compareFullyQualifiedNames(e1, e2);
96 if (result == 0)
97 result = compareModuleNames(e1, e2);
98 return result;
99 }
100 };
101 }
102 return allClassesComparator;
103 }
104
105 private Comparator<Element> packageComparator = null;
106
107 /**
108 * Returns a Comparator for packages, by comparing the fully qualified names,
109 * and if those are equal the names of the enclosing modules.
110 *
111 * @return a Comparator
112 */
113 public Comparator<Element> makePackageComparator() {
114 if (packageComparator == null) {
115 packageComparator = new ElementComparator() {
116 @Override
117 public int compare(Element pkg1, Element pkg2) {
118 int result = compareFullyQualifiedNames(pkg1, pkg2);
119 if (result == 0)
120 result = compareModuleNames(pkg1, pkg2);
121 return result;
122 }
123 };
124 }
125 return packageComparator;
126 }
127
128 private Comparator<Element> deprecatedComparator = null;
129
130 /**
131 * Returns a Comparator for deprecated items listed on deprecated list page, by comparing the
132 * fully qualified names, and if those are equal the names of the enclosing modules.
133 *
134 * @return a Comparator
135 */
136 public Comparator<Element> makeDeprecatedComparator() {
137 if (deprecatedComparator == null) {
138 deprecatedComparator = new ElementComparator() {
139 @Override
140 public int compare(Element e1, Element e2) {
141 int result = compareFullyQualifiedNames(e1, e2);
142 if (result == 0)
143 result = compareModuleNames(e1, e2);
144 return result;
145 }
146 };
147 }
148 return deprecatedComparator;
149 }
150
151 private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
152
153 /**
154 * Returns a Comparator for SerialFieldTree.
155 * @return a Comparator
156 */
157 public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
158 if (serialFieldTreeComparator == null) {
159 serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> {
160 String s1 = o1.getName().toString();
161 String s2 = o2.getName().toString();
162 return s1.compareTo(s2);
163 };
164 }
203 return result;
204 return compareElementKinds(o1, o2);
205 }
206 };
207 }
208 return overrideUseComparator;
209 }
210
211 private Comparator<Element> indexUseComparator = null;
212
213 /**
214 * Returns an {@code Element} Comparator for index file presentations, and are sorted as follows.
215 * If comparing modules and/or packages then simply compare the qualified names,
216 * if comparing a module or a package with a type/member then compare the
217 * FullyQualifiedName of the module or a package with the SimpleName of the entity,
218 * otherwise:
219 * 1. compare the ElementKind ex: Module, Package, Interface etc.
220 * 2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
221 * a case insensitive comparison of parameter the type signatures
222 * 2b. if equal, case sensitive comparison of the type signatures
223 * 3. if equal, compare the FQNs of the entities
224 * 4. finally, if equal, compare the names of the enclosing modules
225 * @return an element comparator for index file use
226 */
227 public Comparator<Element> makeIndexElementComparator() {
228 if (indexUseComparator == null) {
229 indexUseComparator = new ElementComparator() {
230 /**
231 * Compares two elements.
232 *
233 * @param e1 - an element.
234 * @param e2 - an element.
235 * @return a negative integer, zero, or a positive integer as the first
236 * argument is less than, equal to, or greater than the second.
237 */
238 @Override
239 public int compare(Element e1, Element e2) {
240 int result;
241 // first, compare names as appropriate
242 if ((utils.isModule(e1) || utils.isPackage(e1)) && (utils.isModule(e2) || utils.isPackage(e2))) {
243 result = compareFullyQualifiedNames(e1, e2);
244 } else if (utils.isModule(e1) || utils.isPackage(e1)) {
254 // if names are the same, compare element kinds
255 result = compareElementKinds(e1, e2);
256 if (result != 0) {
257 return result;
258 }
259 // if element kinds are the same, and are methods,
260 // compare the method parameters
261 if (hasParameters(e1)) {
262 List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
263 List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
264 result = compareParameters(false, parameters1, parameters2);
265 if (result != 0) {
266 return result;
267 }
268 result = compareParameters(true, parameters1, parameters2);
269 if (result != 0) {
270 return result;
271 }
272 }
273 // else fall back on fully qualified names
274 result = compareFullyQualifiedNames(e1, e2);
275 if (result != 0)
276 return result;
277 return compareModuleNames(e1, e2);
278 }
279 };
280 }
281 return indexUseComparator;
282 }
283
284 /**
285 * Returns a comparator for the {@code IndexItem}s in the index page. This is a composite
286 * comparator that must be able to compare all kinds {@code Element}s as well as
287 * {@code SearchIndexItem}s.
288 *
289 * @return a comparator for index page items.
290 */
291 public Comparator<IndexItem> makeIndexComparator(boolean classesOnly) {
292 Comparator<Element> elementComparator = classesOnly
293 ? makeAllClassesComparator()
294 : makeIndexElementComparator();
295 Comparator<SearchIndexItem> searchTagComparator =
296 makeGenericSearchIndexComparator();
297
341 */
342 public Comparator<TypeMirror> makeTypeMirrorIndexUseComparator() {
343 if (typeMirrorIndexUseComparator == null) {
344 typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> {
345 int result = utils.compareStrings(utils.getTypeName(t1, false), utils.getTypeName(t2, false));
346 if (result != 0)
347 return result;
348 return utils.compareStrings(utils.getQualifiedTypeName(t1), utils.getQualifiedTypeName(t2));
349 };
350 }
351 return typeMirrorIndexUseComparator;
352 }
353
354 private Comparator<Element> classUseComparator = null;
355
356 /**
357 * Comparator for ClassUse presentations, and sorts as follows:
358 * 1. member names
359 * 2. then fully qualified member names
360 * 3. then parameter types if applicable
361 * 4. the element kinds ie. package, class, interface etc.
362 * 5. finally the name of the enclosing modules
363 * @return a comparator to sort classes and members for class use
364 */
365 public Comparator<Element> makeClassUseComparator() {
366 if (classUseComparator == null) {
367 classUseComparator = new ElementComparator() {
368 /**
369 * Compares two Elements.
370 *
371 * @param e1 - an element.
372 * @param e2 - an element.
373 * @return a negative integer, zero, or a positive integer as the first
374 * argument is less than, equal to, or greater than the second.
375 */
376 @Override
377 public int compare(Element e1, Element e2) {
378 int result = compareNames(e1, e2);
379 if (result != 0) {
380 return result;
381 }
382 result = compareFullyQualifiedNames(e1, e2);
383 if (result != 0) {
384 return result;
385 }
386 if (hasParameters(e1) && hasParameters(e2)) {
387 List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
388 List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
389 result = compareParameters(false, parameters1, parameters2);
390 if (result != 0) {
391 return result;
392 }
393 result = compareParameters(true, parameters1, parameters2);
394 }
395 if (result != 0) {
396 return result;
397 }
398 result = compareElementKinds(e1, e2);
399 if (result != 0) {
400 return result;
401 }
402 return compareModuleNames(e1, e2);
403 }
404 };
405 }
406 return classUseComparator;
407 }
408
409 /**
410 * A general purpose comparator to sort Element entities, basically provides the building blocks
411 * for creating specific comparators for an use-case.
412 */
413 private abstract class ElementComparator implements Comparator<Element> {
414 public ElementComparator() { }
415
416 /**
417 * compares two parameter arrays by first comparing the length of the arrays, and
418 * then each Type of the parameter in the array.
419 * @param params1 the first parameter array.
420 * @param params2 the first parameter array.
421 * @return a negative integer, zero, or a positive integer as the first
422 * argument is less than, equal to, or greater than the second.
467 * argument is less than, equal to, or greater than the second.
468 */
469 protected int compareNames(Element e1, Element e2) {
470 return utils.compareStrings(utils.getSimpleName(e1), utils.getSimpleName(e2));
471 }
472
473 /**
474 * Compares the fully qualified names of the entities
475 * @param e1 the first Element.
476 * @param e2 the first Element.
477 * @return a negative integer, zero, or a positive integer as the first
478 * argument is less than, equal to, or greater than the second.
479 */
480 protected int compareFullyQualifiedNames(Element e1, Element e2) {
481 // add simplename to be compatible
482 String thisElement = getFullyQualifiedName(e1);
483 String thatElement = getFullyQualifiedName(e2);
484 return utils.compareStrings(thisElement, thatElement);
485 }
486
487 /**
488 * Compares the name of the modules of two elements.
489 * @param e1 the first element
490 * @param e2 the second element
491 * @return a negative integer, zero, or a positive integer as the first
492 * argument is less than, equal to, or greater than the second
493 */
494 protected int compareModuleNames(Element e1, Element e2) {
495 ModuleElement m1 = utils.elementUtils.getModuleOf(e1);
496 ModuleElement m2 = utils.elementUtils.getModuleOf(e2);
497 if (m1 != null && m2 != null) {
498 return compareFullyQualifiedNames(m1, m2);
499 } else if (m1 != null) {
500 return 1;
501 } else if (m2 != null) {
502 return -1;
503 }
504 return 0;
505 }
506
507 protected int compareElementKinds(Element e1, Element e2) {
508 return Integer.compare(getKindIndex(e1), getKindIndex(e2));
509 }
510
511 private int getKindIndex(Element e) {
512 switch (e.getKind()) {
513 case MODULE: return 0;
514 case PACKAGE: return 1;
515 case CLASS: return 2;
516 case ENUM: return 3;
517 case ENUM_CONSTANT: return 4;
518 case RECORD: return 5;
519 case INTERFACE: return 6;
520 case ANNOTATION_TYPE: return 7;
521 case FIELD: return 8;
522 case CONSTRUCTOR: return 9;
523 case METHOD: return 10;
524 default: throw new IllegalArgumentException(e.getKind().toString());
525 }
526 }
|