Home | History | Annotate | Download | only in writer
      1 /*
      2  * Copyright 2014, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  *     * Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  *     * Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  *     * Neither the name of Google Inc. nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 package org.jf.dexlib2.writer;
     33 
     34 import com.google.common.collect.ImmutableSet;
     35 import com.google.common.collect.Iterables;
     36 import com.google.common.collect.Lists;
     37 import junit.framework.Assert;
     38 import org.jf.dexlib2.AnnotationVisibility;
     39 import org.jf.dexlib2.Opcodes;
     40 import org.jf.dexlib2.dexbacked.DexBackedDexFile;
     41 import org.jf.dexlib2.iface.Annotation;
     42 import org.jf.dexlib2.iface.AnnotationElement;
     43 import org.jf.dexlib2.iface.ClassDef;
     44 import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
     45 import org.jf.dexlib2.immutable.ImmutableAnnotation;
     46 import org.jf.dexlib2.immutable.ImmutableAnnotationElement;
     47 import org.jf.dexlib2.immutable.ImmutableClassDef;
     48 import org.jf.dexlib2.immutable.ImmutableDexFile;
     49 import org.jf.dexlib2.immutable.value.ImmutableAnnotationEncodedValue;
     50 import org.jf.dexlib2.immutable.value.ImmutableNullEncodedValue;
     51 import org.jf.dexlib2.writer.io.MemoryDataStore;
     52 import org.jf.dexlib2.writer.pool.DexPool;
     53 import org.junit.Test;
     54 
     55 import java.io.IOException;
     56 import java.util.List;
     57 
     58 public class DexWriterTest {
     59     @Test
     60     public void testAnnotationElementOrder() {
     61         // Elements are out of order wrt to the element name
     62         ImmutableSet<ImmutableAnnotationElement> elements =
     63                 ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE),
     64                         new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE));
     65 
     66         ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME,
     67                 "Lorg/test/anno;", elements);
     68 
     69         ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;",
     70                 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null);
     71 
     72         MemoryDataStore dataStore = new MemoryDataStore();
     73 
     74         try {
     75             DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.forApi(19), ImmutableSet.of(classDef)));
     76         } catch (IOException ex) {
     77             throw new RuntimeException(ex);
     78         }
     79 
     80         DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dataStore.getData());
     81         ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
     82         Assert.assertNotNull(dbClassDef);
     83         Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
     84         Assert.assertNotNull(dbAnnotation);
     85         List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotation.getElements());
     86 
     87         // Ensure that the elements were written out in sorted order
     88         Assert.assertEquals(2, dbElements.size());
     89         Assert.assertEquals("blah", dbElements.get(0).getName());
     90         Assert.assertEquals("zabaglione", dbElements.get(1).getName());
     91     }
     92 
     93     @Test
     94     public void testEncodedAnnotationElementOrder() {
     95         // Elements are out of order wrt to the element name
     96         ImmutableSet<ImmutableAnnotationElement> encodedElements =
     97                 ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE),
     98                         new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE));
     99 
    100         ImmutableAnnotationEncodedValue encodedAnnotations =
    101                 new ImmutableAnnotationEncodedValue("Lan/encoded/annotation", encodedElements);
    102 
    103         ImmutableSet<ImmutableAnnotationElement> elements =
    104                 ImmutableSet.of(new ImmutableAnnotationElement("encoded_annotation", encodedAnnotations));
    105 
    106         ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME,
    107                 "Lorg/test/anno;", elements);
    108 
    109         ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;",
    110                 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null);
    111 
    112         MemoryDataStore dataStore = new MemoryDataStore();
    113 
    114         try {
    115             DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.forApi(19), ImmutableSet.of(classDef)));
    116         } catch (IOException ex) {
    117             throw new RuntimeException(ex);
    118         }
    119 
    120         DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dataStore.getData());
    121         ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
    122         Assert.assertNotNull(dbClassDef);
    123         Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
    124         Assert.assertNotNull(dbAnnotation);
    125 
    126         AnnotationElement element = Iterables.getFirst(dbAnnotation.getElements(), null);
    127         AnnotationEncodedValue dbAnnotationEncodedValue = (AnnotationEncodedValue)element.getValue();
    128 
    129         List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotationEncodedValue.getElements());
    130 
    131         // Ensure that the elements were written out in sorted order
    132         Assert.assertEquals(2, dbElements.size());
    133         Assert.assertEquals("blah", dbElements.get(0).getName());
    134         Assert.assertEquals("zabaglione", dbElements.get(1).getName());
    135     }
    136 }
    137