001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.automation.core.impl;
020
021import java.lang.reflect.ParameterizedType;
022import java.lang.reflect.Type;
023import java.util.Collection;
024import java.util.Iterator;
025import java.util.List;
026import java.util.ListIterator;
027
028import org.nuxeo.ecm.automation.OutputCollector;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public class IterableInputHelper {
034
035    // protected static ConcurrentMap<String,String> cache;
036
037    private IterableInputHelper() {
038    }
039
040    public static Class<?> getIterableType(Class<?> cl) {
041        // TODO first look into a cache
042        // Class<?> cl = cache.get(cl.getName());
043        return findIterableType(cl);
044    }
045
046    @SuppressWarnings("rawtypes")
047    public static Type[] findCollectorTypes(Class<? extends OutputCollector> cl) {
048        for (Type itf : cl.getGenericInterfaces()) {
049            if (itf instanceof ParameterizedType) {
050                ParameterizedType ptype = (ParameterizedType) itf;
051                if (ptype.getRawType() == OutputCollector.class) {
052                    return ptype.getActualTypeArguments();
053                }
054            }
055        }
056        throw new IllegalArgumentException("Invalid output collector class: " + cl
057                + ". The class must explicitely impelement the OutputCollector interface.");
058    }
059
060    public static Class<?> findIterableType(Class<?> cl) {
061        if (!Iterable.class.isAssignableFrom(cl)) {
062            return null;
063        }
064        // try generic super class
065        Type superType = cl.getGenericSuperclass();
066        if (superType instanceof ParameterizedType) {
067            ParameterizedType ptype = (ParameterizedType) superType;
068            return (Class<?>) ptype.getActualTypeArguments()[0];
069        }
070        // try generic interfaces
071        for (Type itf : cl.getGenericInterfaces()) {
072            if (itf instanceof ParameterizedType) {
073                ParameterizedType ptype = (ParameterizedType) itf;
074                if (ptype.getRawType() == Iterable.class || ptype.getRawType() == Collection.class
075                        || ptype.getRawType() == List.class) {
076                    return (Class<?>) ptype.getActualTypeArguments()[0];
077                }
078            }
079        }
080        // if not descend into the super type and continue.
081        if (superType != null) {
082            Class<?> superClass = cl.getSuperclass();
083            if (superClass != null) {
084                return getIterableType(superClass);
085            }
086        }
087        return null;
088    }
089
090    static class MyIt implements Iterable<String> {
091        @Override
092        public Iterator<String> iterator() {
093            return null;
094        }
095    }
096
097    static class MyList implements List<String> {
098
099        @Override
100        public int size() {
101            return 0;
102        }
103
104        @Override
105        public boolean isEmpty() {
106            return false;
107        }
108
109        @Override
110        public boolean contains(Object o) {
111            return false;
112        }
113
114        @Override
115        public Iterator<String> iterator() {
116            return null;
117        }
118
119        @Override
120        public Object[] toArray() {
121            return null;
122        }
123
124        @Override
125        public <T> T[] toArray(T[] a) {
126            return null;
127        }
128
129        @Override
130        public boolean add(String e) {
131            return false;
132        }
133
134        @Override
135        public boolean remove(Object o) {
136            return false;
137        }
138
139        @Override
140        public boolean containsAll(Collection<?> c) {
141            return false;
142        }
143
144        @Override
145        public boolean addAll(Collection<? extends String> c) {
146            return false;
147        }
148
149        @Override
150        public boolean addAll(int index, Collection<? extends String> c) {
151            return false;
152        }
153
154        @Override
155        public boolean removeAll(Collection<?> c) {
156            return false;
157        }
158
159        @Override
160        public boolean retainAll(Collection<?> c) {
161            return false;
162        }
163
164        @Override
165        public void clear() {
166        }
167
168        @Override
169        public String get(int index) {
170            return null;
171        }
172
173        @Override
174        public String set(int index, String element) {
175            return null;
176        }
177
178        @Override
179        public void add(int index, String element) {
180        }
181
182        @Override
183        public String remove(int index) {
184            return null;
185        }
186
187        @Override
188        public int indexOf(Object o) {
189            return 0;
190        }
191
192        @Override
193        public int lastIndexOf(Object o) {
194            return 0;
195        }
196
197        @Override
198        public ListIterator<String> listIterator() {
199            return null;
200        }
201
202        @Override
203        public ListIterator<String> listIterator(int index) {
204            return null;
205        }
206
207        @Override
208        public List<String> subList(int fromIndex, int toIndex) {
209            return null;
210        }
211
212    }
213
214    static class MyCol implements Collection<String> {
215
216        @Override
217        public int size() {
218            return 0;
219        }
220
221        @Override
222        public boolean isEmpty() {
223            return false;
224        }
225
226        @Override
227        public boolean contains(Object o) {
228            return false;
229        }
230
231        @Override
232        public Iterator<String> iterator() {
233            return null;
234        }
235
236        @Override
237        public Object[] toArray() {
238            return null;
239        }
240
241        @Override
242        public <T> T[] toArray(T[] a) {
243            return null;
244        }
245
246        @Override
247        public boolean add(String e) {
248            return false;
249        }
250
251        @Override
252        public boolean remove(Object o) {
253            return false;
254        }
255
256        @Override
257        public boolean containsAll(Collection<?> c) {
258            return false;
259        }
260
261        @Override
262        public boolean addAll(Collection<? extends String> c) {
263            return false;
264        }
265
266        @Override
267        public boolean removeAll(Collection<?> c) {
268            return false;
269        }
270
271        @Override
272        public boolean retainAll(Collection<?> c) {
273            return false;
274        }
275
276        @Override
277        public void clear() {
278        }
279    }
280
281}