AnnotationItem.java revision 928790f2939e0eec7ab2e4653a19c6c27a113634
1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2009 Ben Gruver 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.dexlib; 30 31import org.jf.dexlib.EncodedValue.AnnotationEncodedSubValue; 32import org.jf.dexlib.Util.Input; 33import org.jf.dexlib.Util.AnnotatedOutput; 34 35public class AnnotationItem extends Item<AnnotationItem> { 36 private int hashCode = 0; 37 38 private AnnotationVisibility visibility; 39 private AnnotationEncodedSubValue annotationValue; 40 41 /** 42 * Creates a new uninitialized <code>AnnotationItem</code> 43 * @param dexFile The <code>DexFile</code> that this item belongs to 44 */ 45 protected AnnotationItem(DexFile dexFile) { 46 super(dexFile); 47 } 48 49 /** 50 * Creates a new <code>AnnotationItem</code> with the given values 51 * @param dexFile The <code>DexFile</code> that this item belongs to 52 * @param visibility The visibility of this annotation 53 * @param annotationValue The value of this annotation 54 */ 55 private AnnotationItem(DexFile dexFile, AnnotationVisibility visibility, 56 AnnotationEncodedSubValue annotationValue) { 57 super(dexFile); 58 this.visibility = visibility; 59 this.annotationValue = annotationValue; 60 } 61 62 /** 63 * Returns an <code>AnnotationItem</code> for the given values, and that has been interned into the given 64 * <code>DexFile</code> 65 * @param dexFile The <code>DexFile</code> that this item belongs to 66 * @param visibility The visibility of this annotation 67 * @param annotationValue The value of this annotation 68 * @return an <code>AnnotationItem</code> for the given values, and that has been interned into the given 69 * <code>DexFile</code> 70 */ 71 public static AnnotationItem internAnnotationItem(DexFile dexFile, AnnotationVisibility visibility, 72 AnnotationEncodedSubValue annotationValue) { 73 AnnotationItem annotationItem = new AnnotationItem(dexFile, visibility, annotationValue); 74 return dexFile.AnnotationsSection.intern(annotationItem); 75 } 76 77 /** {@inheritDoc} */ 78 protected void readItem(Input in, ReadContext readContext) { 79 visibility = AnnotationVisibility.fromByte(in.readByte()); 80 annotationValue = new AnnotationEncodedSubValue(dexFile, in); 81 } 82 83 /** {@inheritDoc} */ 84 protected int placeItem(int offset) { 85 return annotationValue.placeValue(offset + 1); 86 } 87 88 /** {@inheritDoc} */ 89 protected void writeItem(AnnotatedOutput out) { 90 if (out.annotates()) { 91 out.annotate("visibility: " + visibility.name()); 92 out.writeByte(visibility.value); 93 annotationValue.writeValue(out); 94 }else { 95 out.writeByte(visibility.value); 96 annotationValue.writeValue(out); 97 } 98 } 99 100 /** {@inheritDoc} */ 101 public ItemType getItemType() { 102 return ItemType.TYPE_ANNOTATION_ITEM; 103 } 104 105 /** {@inheritDoc} */ 106 public String getConciseIdentity() { 107 return "annotation_item @0x" + Integer.toHexString(getOffset()); 108 } 109 110 /** {@inheritDoc} */ 111 public int compareTo(AnnotationItem o) { 112 int comp = visibility.value - o.visibility.value; 113 if (comp == 0) { 114 comp = annotationValue.compareTo(o.annotationValue); 115 } 116 return comp; 117 } 118 119 /** 120 * @return The visibility of this annotation 121 */ 122 public AnnotationVisibility getVisibility() { 123 return visibility; 124 } 125 126 /** 127 * @return The encoded annotation value of this annotation 128 */ 129 public AnnotationEncodedSubValue getEncodedAnnotation() { 130 return annotationValue; 131 } 132 133 /** 134 * calculate and cache the hashcode 135 */ 136 private void calcHashCode() { 137 hashCode = visibility.value; 138 hashCode = hashCode * 31 + annotationValue.hashCode(); 139 } 140 141 @Override 142 public int hashCode() { 143 //there's a small possibility that the actual hash code will be 0. If so, we'll 144 //just end up recalculating it each time 145 if (hashCode == 0) 146 calcHashCode(); 147 return hashCode; 148 } 149 150 @Override 151 public boolean equals(Object o) { 152 if (this==o) { 153 return true; 154 } 155 if (o==null || !this.getClass().equals(o.getClass())) { 156 return false; 157 } 158 159 AnnotationItem other = (AnnotationItem)o; 160 return visibility == other.visibility && annotationValue.equals(other.annotationValue); 161 } 162} 163