ImmutableConverter.java revision 22c3185bb7c8618437eabe6c597549e0989ec4e6
1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Copyright 2012, Google Inc. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * All rights reserved. 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Redistribution and use in source and binary forms, with or without 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * modification, are permitted provided that the following conditions are 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * met: 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * * Redistributions of source code must retain the above copyright 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * notice, this list of conditions and the following disclaimer. 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * * Redistributions in binary form must reproduce the above 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * copyright notice, this list of conditions and the following disclaimer 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * in the documentation and/or other materials provided with the 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * distribution. 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * * Neither the name of Google Inc. nor the names of its 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * contributors may be used to endorse or promote products derived from 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * this software without specific prior written permission. 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpackage org.jf.util; 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport com.google.common.collect.ImmutableList; 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport com.google.common.collect.ImmutableSet; 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport com.google.common.collect.ImmutableSortedSet; 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport javax.annotation.Nonnull; 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport javax.annotation.Nullable; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport java.util.Comparator; 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport java.util.Iterator; 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathimport java.util.SortedSet; 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic abstract class ImmutableConverter<ImmutableItem, Item> { 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected abstract boolean isImmutable(@Nonnull Item item); 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Nonnull protected abstract ImmutableItem makeImmutable(@Nonnull Item item); 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Nonnull 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public ImmutableList<ImmutableItem> toList(@Nullable final Iterable<? extends Item> iterable) { 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (iterable == null) { 517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return ImmutableList.of(); 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath boolean needsCopy = false; 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (iterable instanceof ImmutableList) { 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Item element: iterable) { 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (!isImmutable(element)) { 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath needsCopy = true; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath break; 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } else { 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath needsCopy = true; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (!needsCopy) { 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return (ImmutableList<ImmutableItem>)iterable; 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath final Iterator<? extends Item> iter = iterable.iterator(); 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return ImmutableList.copyOf(new Iterator<ImmutableItem>() { 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Override public boolean hasNext() { return iter.hasNext(); } 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Override public ImmutableItem next() { return makeImmutable(iter.next()); } 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Override public void remove() { iter.remove(); } 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }); 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath @Nonnull 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public ImmutableSet<ImmutableItem> toSet(@Nullable final Iterable<? extends Item> iterable) { 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (iterable == null) { 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return ImmutableSet.of(); 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath boolean needsCopy = false; 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (iterable instanceof ImmutableSet) { 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Item element: iterable) { 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 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