KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > transformation > FilterTransformer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.transformation;
17
18 import org.apache.avalon.framework.parameters.Parameters;
19 import org.apache.cocoon.ProcessingException;
20 import org.apache.cocoon.caching.CacheableProcessingComponent;
21 import org.apache.cocoon.environment.SourceResolver;
22 import org.apache.excalibur.source.SourceValidity;
23 import org.apache.excalibur.source.impl.validity.NOPValidity;
24 import org.xml.sax.Attributes JavaDoc;
25 import org.xml.sax.SAXException JavaDoc;
26 import org.xml.sax.helpers.AttributesImpl JavaDoc;
27
28 import java.io.IOException JavaDoc;
29 import java.util.Map JavaDoc;
30
31 /**
32  * @cocoon.sitemap.component.documentation
33  * The filter transformer can be used to let only an amount of elements through in
34  * a given block.
35  *
36  * @cocoon.sitemap.component.name filter
37  * @cocoon.sitemap.component.documentation.caching TBD
38  * @cocoon.sitemap.component.logger sitemap.transformer.filter
39  *
40  *
41  * The filter transformer can be used to let only an amount of elements through in
42  * a given block.
43  *
44  * <p>Usage in the sitemap:
45  * &lt;map:transform type="filter"&gt;
46  * &lt;map:parameter name="element-name" value="row"/&gt;
47  * &lt;map:parameter name="count" value="5"/&gt;
48  * &lt;map:parameter name="blocknr" value="3"/&gt;
49  * &lt;/map:transform&gt;
50  *
51  * <p>Only the 3rd block will be shown, containing only 5 row elements.
52  *
53  * <p><b>Known limitation: behaviour of transformer when trigger elements are nested
54  * is not predictable.</b>
55  *
56  * @author <a HREF="mailto:sven.beauprez@the-ecorp.com">Sven Beauprez</a>
57  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
58  * @version CVS $Id: FilterTransformer.java 43324 2004-09-04 05:11:48Z crossley $
59  */

60 public class FilterTransformer
61 extends AbstractTransformer
62 implements CacheableProcessingComponent {
63     
64     private static final String JavaDoc ELEMENT = "element-name";
65     private static final String JavaDoc COUNT = "count";
66     private static final String JavaDoc BLOCKNR = "blocknr";
67     private static final String JavaDoc BLOCK = "block";
68     private static final String JavaDoc BLOCKID = "id";
69     private static final int DEFAULT_COUNT = 10;
70     private static final int DEFAULT_BLOCK = 1;
71     
72     protected int counter;
73     protected int count;
74     protected int blocknr;
75     protected int currentBlocknr;
76     protected String JavaDoc elementName;
77     protected String JavaDoc parentName;
78     protected boolean skip;
79     protected boolean foundIt;
80     
81     /** BEGIN SitemapComponent methods **/
82     public void setup(SourceResolver resolver,
83     Map JavaDoc objectModel,
84     String JavaDoc source,
85     Parameters parameters)
86     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
87         this.counter=0;
88         this.currentBlocknr=0;
89         this.skip=false;
90         this.foundIt=false;
91         this.parentName=null;
92         this.elementName = parameters.getParameter(ELEMENT, "");
93         this.count = parameters.getParameterAsInteger(COUNT, DEFAULT_COUNT);
94         this.blocknr = parameters.getParameterAsInteger(BLOCKNR, DEFAULT_BLOCK);
95         if (this.elementName == null || this.elementName.equals("") || this.count == 0) {
96             throw new ProcessingException("FilterTransformer: both "+ ELEMENT + " and " +
97             COUNT + " parameters need to be specified");
98         }
99     }
100     
101     /**
102      * Generate the unique key.
103      * This key must be unique inside the space of this component.
104      * This method must be invoked before the generateValidity() method.
105      *
106      * @return The generated key or <code>0</code> if the component
107      * is currently not cacheable.
108      */

109     public java.io.Serializable JavaDoc getKey() {
110         return this.elementName + '<' + this.count + '>' + this.blocknr;
111     }
112     
113     /**
114      * Generate the validity object.
115      * Before this method can be invoked the generateKey() method
116      * must be invoked.
117      *
118      * @return The generated validity object or <code>null</code> if the
119      * component is currently not cacheable.
120      */

121     public SourceValidity getValidity() {
122         return NOPValidity.SHARED_INSTANCE;
123     }
124     
125     /** BEGIN SAX ContentHandler handlers **/
126     public void startElement(String JavaDoc uri, String JavaDoc name, String JavaDoc raw, Attributes JavaDoc attributes)
127     throws SAXException JavaDoc {
128         if (name.equalsIgnoreCase(elementName)) {
129             this.foundIt = true;
130             this.counter++;
131             if (this.counter <= (this.count*(this.blocknr)) && this.counter > (this.count*(this.blocknr-1))) {
132                 this.skip = false;
133             } else {
134                 this.skip = true;
135             }
136             if (this.currentBlocknr != (int)Math.ceil((float)this.counter/this.count)) {
137                 this.currentBlocknr = (int)Math.ceil((float)this.counter/this.count);
138                 AttributesImpl JavaDoc attr = new AttributesImpl JavaDoc();
139                 attr.addAttribute("", BLOCKID, BLOCKID, "CDATA", String.valueOf(this.currentBlocknr));
140                 if (this.counter < this.count) {
141                     super.contentHandler.startElement("", BLOCK, BLOCK, attr);
142                 } else {
143                     // fix Bugzilla Bug 13904, check if counter == 1
144
// in this case there is no startElement("", BLOCK, BLOCK)
145
// written, yet
146
if (this.counter > 1) {
147                         super.contentHandler.endElement("", BLOCK, BLOCK);
148                     }
149                     super.contentHandler.startElement("", BLOCK, BLOCK, attr);
150                 }
151             }
152         } else if (!this.foundIt) {
153             this.parentName = name;
154         }
155         if (!this.skip) {
156             super.contentHandler.startElement(uri,name,raw,attributes);
157         }
158     }
159     
160     public void endElement(String JavaDoc uri,String JavaDoc name,String JavaDoc raw)
161     throws SAXException JavaDoc {
162         if (this.foundIt && name.equals(this.parentName)) {
163             // FIXME: VG: This will fail on XML like:
164
// <parent>
165
// <element>
166
// <parent>
167
super.contentHandler.endElement("", BLOCK, BLOCK);
168             super.contentHandler.endElement(uri, name, raw);
169             this.foundIt = false;
170             this.skip = false;
171         } else if (!this.skip) {
172             super.contentHandler.endElement(uri,name,raw);
173         }
174     }
175     
176     public void characters(char c[], int start, int len)
177     throws SAXException JavaDoc {
178         if (!this.skip) {
179             super.contentHandler.characters(c,start,len);
180         }
181     }
182     
183     public void processingInstruction(String JavaDoc target, String JavaDoc data)
184     throws SAXException JavaDoc {
185         if (!this.skip) {
186             super.contentHandler.processingInstruction(target, data);
187         }
188     }
189     
190     public void startEntity(String JavaDoc name)
191     throws SAXException JavaDoc {
192         if (!this.skip) {
193             super.lexicalHandler.startEntity(name);
194         }
195     }
196     
197     public void endEntity(String JavaDoc name)
198     throws SAXException JavaDoc {
199         if (!this.skip) {
200             super.lexicalHandler.endEntity( name);
201         }
202     }
203     
204     public void startCDATA()
205     throws SAXException JavaDoc {
206         if (!this.skip) {
207             super.lexicalHandler.startCDATA();
208         }
209     }
210     
211     public void endCDATA()
212     throws SAXException JavaDoc {
213         if (!this.skip) {
214             super.lexicalHandler.endCDATA();
215         }
216     }
217     
218     public void comment(char ch[], int start, int len)
219     throws SAXException JavaDoc {
220         if (!this.skip) {
221             super.lexicalHandler.comment(ch, start, len);
222         }
223     }
224 }
225
Popular Tags