1 /* 2 * Copyright 2012, Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google LLC nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 package com.android.tools.smali.util; 32 33 import static java.util.Collections.unmodifiableList; 34 import static java.util.Collections.unmodifiableSet; 35 import static java.util.Collections.unmodifiableSortedSet; 36 37 import javax.annotation.Nonnull; 38 import javax.annotation.Nullable; 39 import java.util.ArrayList; 40 import java.util.Collections; 41 import java.util.Comparator; 42 import java.util.HashSet; 43 import java.util.Iterator; 44 import java.util.List; 45 import java.util.Set; 46 import java.util.SortedSet; 47 import java.util.TreeSet; 48 49 public abstract class ImmutableConverter<ImmutableItem, Item> { isImmutable(@onnull Item item)50 protected abstract boolean isImmutable(@Nonnull Item item); makeImmutable(@onnull Item item)51 @Nonnull protected abstract ImmutableItem makeImmutable(@Nonnull Item item); 52 53 @Nonnull toList(@ullable final Iterable<? extends Item> iterable)54 public List<ImmutableItem> toList(@Nullable final Iterable<? extends Item> iterable) { 55 if (iterable == null) { 56 return Collections.emptyList(); 57 } 58 59 boolean needsCopy = false; 60 if (iterable instanceof List) { 61 for (Item element: iterable) { 62 if (!isImmutable(element)) { 63 needsCopy = true; 64 break; 65 } 66 } 67 } else { 68 needsCopy = true; 69 } 70 71 if (!needsCopy) { 72 return unmodifiableList((List<ImmutableItem>)iterable); 73 } 74 75 final Iterator<? extends Item> iter = iterable.iterator(); 76 77 ArrayList<ImmutableItem> list = new ArrayList<ImmutableItem>(); 78 while (iter.hasNext()) { 79 list.add(makeImmutable(iter.next())); 80 } 81 82 return unmodifiableList(list); 83 } 84 85 @Nonnull toSet(@ullable final Iterable<? extends Item> iterable)86 public Set<ImmutableItem> toSet(@Nullable final Iterable<? extends Item> iterable) { 87 if (iterable == null) { 88 return Collections.emptySet(); 89 } 90 91 boolean needsCopy = false; 92 if (iterable instanceof Set) { 93 for (Item element: iterable) { 94 if (!isImmutable(element)) { 95 needsCopy = true; 96 break; 97 } 98 } 99 } else { 100 needsCopy = true; 101 } 102 103 if (!needsCopy) { 104 return unmodifiableSet((Set<ImmutableItem>)iterable); 105 } 106 107 final Iterator<? extends Item> iter = iterable.iterator(); 108 109 HashSet<ImmutableItem> set = new HashSet<ImmutableItem>(); 110 while (iter.hasNext()) { 111 set.add(makeImmutable(iter.next())); 112 } 113 return unmodifiableSet(set); 114 } 115 116 @Nonnull toSortedSet(@onnull Comparator<? super ImmutableItem> comparator, @Nullable final Iterable<? extends Item> iterable)117 public SortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator, 118 @Nullable final Iterable<? extends Item> iterable) { 119 if (iterable == null) { 120 return Collections.emptySortedSet(); 121 } 122 123 boolean needsCopy = false; 124 if (iterable instanceof SortedSet && 125 ((SortedSet)iterable).comparator().equals(comparator)) { 126 for (Item element: iterable) { 127 if (!isImmutable(element)) { 128 needsCopy = true; 129 break; 130 } 131 } 132 } else { 133 needsCopy = true; 134 } 135 136 if (!needsCopy) { 137 return unmodifiableSortedSet((SortedSet<ImmutableItem>)iterable); 138 } 139 140 final Iterator<? extends Item> iter = iterable.iterator(); 141 142 TreeSet<ImmutableItem> treeSet = new TreeSet<ImmutableItem>(comparator); 143 while (iter.hasNext()) { 144 treeSet.add(makeImmutable(iter.next())); 145 } 146 return unmodifiableSortedSet(treeSet); 147 } 148 } 149