1 /* 2 * Copyright 2012, 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.util; 33 34 import com.google.common.collect.ImmutableList; 35 import com.google.common.collect.ImmutableSet; 36 import com.google.common.collect.ImmutableSortedSet; 37 38 import javax.annotation.Nonnull; 39 import javax.annotation.Nullable; 40 import java.util.Comparator; 41 import java.util.Iterator; 42 import java.util.SortedSet; 43 44 public abstract class ImmutableConverter<ImmutableItem, Item> { isImmutable(@onnull Item item)45 protected abstract boolean isImmutable(@Nonnull Item item); makeImmutable(@onnull Item item)46 @Nonnull protected abstract ImmutableItem makeImmutable(@Nonnull Item item); 47 48 @Nonnull toList(@ullable final Iterable<? extends Item> iterable)49 public ImmutableList<ImmutableItem> toList(@Nullable final Iterable<? extends Item> iterable) { 50 if (iterable == null) { 51 return ImmutableList.of(); 52 } 53 54 boolean needsCopy = false; 55 if (iterable instanceof ImmutableList) { 56 for (Item element: iterable) { 57 if (!isImmutable(element)) { 58 needsCopy = true; 59 break; 60 } 61 } 62 } else { 63 needsCopy = true; 64 } 65 66 if (!needsCopy) { 67 return (ImmutableList<ImmutableItem>)iterable; 68 } 69 70 final Iterator<? extends Item> iter = iterable.iterator(); 71 72 return ImmutableList.copyOf(new Iterator<ImmutableItem>() { 73 @Override public boolean hasNext() { return iter.hasNext(); } 74 @Override public ImmutableItem next() { return makeImmutable(iter.next()); } 75 @Override public void remove() { iter.remove(); } 76 }); 77 } 78 79 @Nonnull 80 public ImmutableSet<ImmutableItem> toSet(@Nullable final Iterable<? extends Item> iterable) { 81 if (iterable == null) { 82 return ImmutableSet.of(); 83 } 84 85 boolean needsCopy = false; 86 if (iterable instanceof ImmutableSet) { 87 for (Item element: iterable) { 88 if (!isImmutable(element)) { 89 needsCopy = true; 90 break; 91 } 92 } 93 } else { 94 needsCopy = true; 95 } 96 97 if (!needsCopy) { 98 return (ImmutableSet<ImmutableItem>)iterable; 99 } 100 101 final Iterator<? extends Item> iter = iterable.iterator(); 102 103 return ImmutableSet.copyOf(new Iterator<ImmutableItem>() { 104 @Override public boolean hasNext() { return iter.hasNext(); } 105 @Override public ImmutableItem next() { return makeImmutable(iter.next()); } 106 @Override public void remove() { iter.remove(); } 107 }); 108 } 109 110 @Nonnull 111 public ImmutableSortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator, 112 @Nullable final Iterable<? extends Item> iterable) { 113 if (iterable == null) { 114 return ImmutableSortedSet.of(); 115 } 116 117 boolean needsCopy = false; 118 if (iterable instanceof ImmutableSortedSet && 119 ((ImmutableSortedSet)iterable).comparator().equals(comparator)) { 120 for (Item element: iterable) { 121 if (!isImmutable(element)) { 122 needsCopy = true; 123 break; 124 } 125 } 126 } else { 127 needsCopy = true; 128 } 129 130 if (!needsCopy) { 131 return (ImmutableSortedSet<ImmutableItem>)iterable; 132 } 133 134 final Iterator<? extends Item> iter = iterable.iterator(); 135 136 137 return ImmutableSortedSet.copyOf(comparator, new Iterator<ImmutableItem>() { 138 @Override public boolean hasNext() { return iter.hasNext(); } 139 @Override public ImmutableItem next() { return makeImmutable(iter.next()); } 140 @Override public void remove() { iter.remove(); } 141 }); 142 } 143 144 @Nonnull 145 public SortedSet<ImmutableItem> toSortedSet(@Nonnull Comparator<? super ImmutableItem> comparator, 146 @Nullable final SortedSet<? extends Item> sortedSet) { 147 if (sortedSet == null || sortedSet.size() == 0) { 148 return ImmutableSortedSet.of(); 149 } 150 151 @SuppressWarnings("unchecked") 152 ImmutableItem[] newItems = (ImmutableItem[])new Object[sortedSet.size()]; 153 int index = 0; 154 for (Item item: sortedSet) { 155 newItems[index++] = makeImmutable(item); 156 } 157 158 return ArraySortedSet.of(comparator, newItems); 159 } 160 } 161