KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > archive > crawler > util > Transform


1 /* Transform
2 *
3 * $Id: Transform.java,v 1.2.2.1 2007/01/13 01:31:30 stack-sf Exp $
4 *
5 * Created on September 26, 2006
6 *
7 * Copyright (C) 2006 Internet Archive.
8 *
9 * This file is part of the Heritrix web crawler (crawler.archive.org).
10 *
11 * Heritrix is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * any later version.
15 *
16 * Heritrix is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser Public License
22 * along with Heritrix; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */

25 package org.archive.crawler.util;
26
27 import java.util.AbstractCollection JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Iterator JavaDoc;
30
31
32 /**
33  * A transformation of a collection. The elements in the transform are based
34  * on the elements of some other collection; the original collection's
35  * elements are transformed using a specified transformer. Changes to the
36  * original collection are automatically reflected in the transform and
37  * vice-versa.
38  *
39  * <p>If the transformer returns null for a given original object, then that
40  * object will not be included in the transform. Thus the transform might
41  * be smaller than the original collection. Note that Transform instances
42  * can never contain the null element.
43  *
44  * <p>This collection implementation does not support the optional add
45  * operation.
46  *
47  * @author pjack
48  *
49  * @param <Original> the type of the original elements in the collection
50  * @param <Transformed> the type of the tranformed elements
51  */

52 public class Transform<Original,Transformed>
53 extends AbstractCollection JavaDoc<Transformed> {
54
55     /** The original collection. */
56     final private Collection JavaDoc<? extends Original> delegate;
57     
58     /** Transforms the original objects. */
59     final private Transformer<Original,Transformed> transformer;
60     
61     /**
62      * Constructor.
63      *
64      * @param delegate The collection whose elements to transform.
65      * @param transformer Transforms the elements
66      */

67     public Transform(Collection JavaDoc<? extends Original> delegate,
68             Transformer<Original,Transformed> transformer) {
69         this.delegate = delegate;
70         this.transformer = transformer;
71     }
72     
73     public int size() {
74         int count = 0;
75         Iterator JavaDoc<Transformed> iter = iterator();
76         while (iter.hasNext()) {
77             iter.next();
78             count++;
79         }
80         return count;
81     }
82
83     public Iterator JavaDoc<Transformed> iterator() {
84         return new TransformIterator<Original,Transformed>(
85                 delegate.iterator(), transformer);
86     }
87     
88     
89     /**
90      * Returns a transform containing only objects of a given class.
91      *
92      * @param <Target> the target class
93      * @param c the collection to transform
94      * @param cls the class of objects to return
95      * @return a collection containing only objects of class cls
96      */

97     public static <Target> Collection JavaDoc<Target> subclasses(
98             Collection JavaDoc<? extends Object JavaDoc> c,
99             final Class JavaDoc<Target> cls) {
100         Transformer<Object JavaDoc,Target> t = new Transformer<Object JavaDoc,Target>() {
101             public Target transform(Object JavaDoc s) {
102                 if (cls.isInstance(s)) {
103                     return cls.cast(s);
104                 } else {
105                     return null;
106                 }
107             }
108         };
109         return new Transform<Object JavaDoc,Target>(c, t);
110     }
111 }
112
113
114 class TransformIterator<Original,Transformed> implements Iterator JavaDoc<Transformed> {
115
116     final private Iterator JavaDoc<? extends Original> iterator;
117     final private Transformer<Original,Transformed> transformer;
118     private Transformed next;
119     
120     public TransformIterator(Iterator JavaDoc<? extends Original> iterator,
121             Transformer<Original,Transformed> transformer) {
122         this.iterator = iterator;
123         this.transformer = transformer;
124     }
125     
126     public boolean hasNext() {
127         if (next != null) {
128             return true;
129         }
130         while (iterator.hasNext()) {
131             Original o = iterator.next();
132             next = transformer.transform(o);
133             if (next != null) {
134                 return true;
135             }
136         }
137         return false;
138     }
139
140     public Transformed next() {
141         if (!hasNext()) {
142             throw new IllegalStateException JavaDoc();
143         }
144         Transformed r = next;
145         next = null;
146         return r;
147     }
148
149     // FIXME: this can break standard Iterator contract, for example
150
// transformIterator.next();
151
// if(transformIterator.hasNext()) {
152
// transformIterator.remove();
153
// }
154
// usual iterator contract is to remove the last object returned
155
// by next; in this case the subsequent
156
public void remove() {
157         iterator.remove();
158     }
159     
160 }
Popular Tags