KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > selection > AbstractRegexpSelector


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.selection;
17
18 import java.util.HashMap JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.apache.avalon.framework.configuration.Configurable;
22 import org.apache.avalon.framework.configuration.Configuration;
23 import org.apache.avalon.framework.configuration.ConfigurationException;
24 import org.apache.avalon.framework.thread.ThreadSafe;
25 import org.apache.regexp.RE;
26 import org.apache.regexp.RECompiler;
27 import org.apache.regexp.REProgram;
28 import org.apache.regexp.RESyntaxException;
29
30 /**
31  * <p>The {@link AbstractRegexpSelector} abstract class defines a simple selector
32  * operating over configured regular-expression patterns.</p>
33  *
34  * <p>Configuration of an {@link AbstractRegexpSelector} is quite simple: first of
35  * all the patterns used for selections must be configured:</p>
36  *
37  * <pre>
38  * &lt;map:components&gt;
39  * ...
40  * &lt;map:selectors default="..."&gt;
41  * &lt;map:selector name="..." SRC="org.apache.cocoon.selection...."&gt;
42  * &lt;pattern name="empty"&gt;^$&lt;/pattern&gt;
43  * &lt;pattern name="number"&gt;^[0-9]+$&lt;/pattern&gt;
44  * &lt;pattern name="string"&gt;^.+$&lt;/pattern&gt;
45  * &lt;/map:selector&gt;
46  * &lt;/map:selectors&gt;
47  * &lt;/map:components&gt;
48  * </pre>
49  *
50  * <p>Then, each configured pattern can be referenced in the pipelines section of
51  * the sitemap:</p>
52  *
53  * <pre>
54  * &lt;map:pipelines&gt;
55  * ...
56  * &lt;map:match ...&gt;
57  * ...
58  * &lt;map:select type="browser"&gt;
59  * &lt;map:when test="empty"&gt;...&lt;/map:when&gt;
60  * &lt;map:when test="number"&gt;...&lt;/map:when&gt;
61  * &lt;map:when test="string"&gt;...&lt;/map:when&gt;
62  * &lt;map:otherwise&gt;...&lt;/map:otherwise&gt;
63  * &lt;/map:select&gt;
64  * ...
65  * &lt;/map:match&gt;
66  * ...
67  * &lt;/map:pipelines&gt;
68  * </pre>
69  *
70  * @author <a HREF="mailto:pier@apache.org">Pier Fumagalli</a>
71  * @version CVS $Id: AbstractRegexpSelector.java 30941 2004-07-29 19:56:58Z vgritsenko $
72  */

73 public abstract class AbstractRegexpSelector extends AbstractSwitchSelector
74 implements Configurable, ThreadSafe {
75
76     /** <p>A {@link Map} of regular expression programs by name.</p> */
77     protected Map JavaDoc patterns = new HashMap JavaDoc();
78
79     /**
80      * <p>Create a new {@link AbstractRegexpSelector} instance.</p>
81      */

82     protected AbstractRegexpSelector() {
83         super();
84     }
85
86     /**
87      * <p>Select a pipeline fragment based on a previously configured pattern.</p>
88      *
89      * @param patternName the name of the configured pattern.
90      * @param selectorContext the string to be matched by the named pattern.
91      * @return <b>true</b> if the contexts is matched by the configured pattern.
92      */

93     public boolean select(String JavaDoc patternName, Object JavaDoc selectorContext) {
94
95         /* Check that the context selection returned something */
96         if (selectorContext == null) return(false);
97
98         /* Check that we actually have a configured pattern */
99         REProgram pattern = (REProgram) this.patterns.get(patternName);
100         if (pattern == null) {
101             if (this.getLogger().isWarnEnabled()) {
102                 this.getLogger().warn("The specified pattern name \"" + patternName
103                                       + "\" was not configured in this instance");
104             }
105             return(false);
106         }
107
108         /* Pattern matching */
109         return(new RE(pattern).match(selectorContext.toString()));
110     }
111
112     /**
113      * <p>Configure this instance parsing all regular expression patterns.</p>
114      *
115      * @param configuration the {@link Configuration} instance where configured
116      * patterns are defined.
117      * @throws ConfigurationException if one of the regular-expression to configure
118      * could not be compiled.
119      */

120     public void configure(Configuration configuration)
121     throws ConfigurationException {
122         Configuration patterns[] = configuration.getChildren("pattern");
123         for (int x = 0; x < patterns.length; x++) {
124             String JavaDoc name = patterns[x].getAttribute("name");
125             String JavaDoc pattern = patterns[x].getValue();
126             this.patterns.put(name, this.compile(pattern));
127         }
128     }
129
130     /**
131      * <p>Compile the pattern in a {@link REProgram}.</p>
132      *
133      * @param pattern the regular expression pattern in a textual format.
134      * @return a compiled regular expression pattern.
135      * @throws ConfigurationException in the pattern could not be compiled.
136      */

137     protected REProgram compile(String JavaDoc pattern)
138     throws ConfigurationException {
139         if (pattern == null) {
140             throw new ConfigurationException("Null pattern");
141         }
142
143         if (pattern.length() == 0) {
144             pattern = "^$";
145             if (this.getLogger().isWarnEnabled()) {
146                 this.getLogger().warn("The empty pattern string was rewritten to "
147                                       + "'^$' to match for empty strings. If you "
148                                       + "intended to match all strings, please "
149                                       + "change your pattern to '.*'");
150             }
151         }
152
153         try {
154             RECompiler compiler = new RECompiler();
155             REProgram program = compiler.compile(pattern);
156             return program;
157         } catch (RESyntaxException rse) {
158             getLogger().debug("Failed to compile the pattern '" + pattern + "'", rse);
159             throw new ConfigurationException(rse.getMessage(), rse);
160         }
161     }
162 }
163
Popular Tags