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