/** * Add a set of default values, stored in an annotation class' classfile, to a concrete instance of that * annotation. The defaults are overwritten by any annotation parameter values in the concrete annotation. * * @param defaultAnnotationParamValues * the default parameter values for the annotation. */ void addDefaultValues(final List<AnnotationParamValue> defaultAnnotationParamValues) { if (defaultAnnotationParamValues != null && !defaultAnnotationParamValues.isEmpty()) { if (this.annotationParamValues == null || this.annotationParamValues.isEmpty()) { this.annotationParamValues = new ArrayList<>(defaultAnnotationParamValues); } else { // Overwrite defaults with non-defaults final Map<String, Object> allParamValues = new HashMap<>(); for (final AnnotationParamValue annotationParamValue : defaultAnnotationParamValues) { allParamValues.put(annotationParamValue.paramName, annotationParamValue.paramValue.get()); } for (final AnnotationParamValue annotationParamValue : this.annotationParamValues) { allParamValues.put(annotationParamValue.paramName, annotationParamValue.paramValue.get()); } this.annotationParamValues.clear(); for (final Entry<String, Object> ent : allParamValues.entrySet()) { this.annotationParamValues.add(new AnnotationParamValue(ent.getKey(), ent.getValue())); } } } if (this.annotationParamValues != null) { Collections.sort(this.annotationParamValues); } }
@Override public int compareTo(final AnnotationInfo o) { final int diff = annotationName.compareTo(o.annotationName); if (diff != 0) { return diff; } if (annotationParamValues == null && o.annotationParamValues == null) { return 0; } else if (annotationParamValues == null) { return -1; } else if (o.annotationParamValues == null) { return 1; } else { for (int i = 0, max = Math.max(annotationParamValues.size(), o.annotationParamValues.size()); i < max; i++) { if (i >= annotationParamValues.size()) { return -1; } else if (i >= o.annotationParamValues.size()) { return 1; } else { final int diff2 = annotationParamValues.get(i).compareTo(o.annotationParamValues.get(i)); if (diff2 != 0) { return diff2; } } } } return 0; }
@Override public int compareTo(final AnnotationParamValue o) { final int diff = paramName.compareTo(o.getParamName()); if (diff != 0) { return diff; } // Use toString() order and get() (which can be slow) as a last-ditch effort -- only happens // if the annotation has multiple parameters of the same name but different value. final Object p0 = getParamValue(); final Object p1 = o.getParamValue(); if (p0 == null && p1 == null) { return 0; } else if (p0 == null && p1 != null) { return -1; } else if (p0 != null && p1 == null) { return 1; } return p0.toString().compareTo(p1.toString()); }
.add(new AnnotationParamValue(methodName, annotationParamDefaultValue)); } else { skip(attributeLength);
/** * Render as a string, into a StringBuilder buffer. * * @param buf * The buffer. */ public void toString(final StringBuilder buf) { buf.append("@" + annotationName); if (annotationParamValues != null) { buf.append('('); for (int i = 0; i < annotationParamValues.size(); i++) { if (i > 0) { buf.append(", "); } final AnnotationParamValue annotationParamValue = annotationParamValues.get(i); if (annotationParamValues.size() > 1 || !"value".equals(annotationParamValue.paramName)) { annotationParamValue.toString(buf); } else { annotationParamValue.toStringParamValueOnly(buf); } } buf.append(')'); } }
/** Read annotation entry from classfile. */ private AnnotationInfo readAnnotation() throws IOException, InterruptedException { // Lcom/xyz/Annotation; -> Lcom.xyz.Annotation; final String annotationClassName = getConstantPoolClassDescriptor(readUnsignedShort()); final int numElementValuePairs = readUnsignedShort(); List<AnnotationParamValue> paramVals = null; if (numElementValuePairs > 0) { paramVals = new ArrayList<>(numElementValuePairs); } for (int i = 0; i < numElementValuePairs; i++) { final String paramName = getConstantPoolString(readUnsignedShort()); // skip(2); // element_name_index final Object paramValue = readAnnotationElementValue(); paramVals.add(new AnnotationParamValue(paramName, paramValue)); } return new AnnotationInfo(annotationClassName, paramVals); }
@Override void setScanResult(final ScanResult scanResult) { this.scanResult = scanResult; if (annotationParamValues != null) { for (final AnnotationParamValue a : annotationParamValues) { if (a != null) { a.setScanResult(scanResult); } } } }
void toString(final StringBuilder buf) { buf.append(paramName); buf.append(" = "); toStringParamValueOnly(buf); }
@Override public int hashCode() { int h = annotationName.hashCode(); if (annotationParamValues != null) { for (int i = 0; i < annotationParamValues.size(); i++) { final AnnotationParamValue e = annotationParamValues.get(i); h = h * 7 + e.getParamName().hashCode() * 3 + e.getParamValue().hashCode(); } } return h; }
@Override public boolean equals(final Object obj) { if (!(obj instanceof AnnotationParamValue)) { return false; } final AnnotationParamValue o = (AnnotationParamValue) obj; final int diff = this.compareTo(o); return (diff != 0 ? false : paramValue == null && o.paramValue == null ? true : paramValue == null || o.paramValue == null ? false : true); } }
@Override public String toString() { final StringBuilder buf = new StringBuilder(); toString(buf); return buf.toString(); }