001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.matching.modular;
018:
019: import org.apache.avalon.framework.configuration.Configurable;
020: import org.apache.avalon.framework.configuration.Configuration;
021: import org.apache.avalon.framework.configuration.ConfigurationException;
022: import org.apache.avalon.framework.parameters.Parameters;
023: import org.apache.avalon.framework.component.ComponentSelector;
024: import org.apache.avalon.framework.component.ComponentException;
025: import org.apache.avalon.framework.component.ComponentManager;
026: import org.apache.avalon.framework.component.Composable;
027: import org.apache.avalon.framework.activity.Initializable;
028: import org.apache.avalon.framework.activity.Disposable;
029: import org.apache.avalon.framework.thread.ThreadSafe;
030:
031: import org.apache.cocoon.components.modules.input.InputModule;
032:
033: import org.apache.cocoon.matching.AbstractWildcardMatcher;
034:
035: import java.util.Map;
036:
037: /**
038: * Matches against a wildcard expression. Needs an input module to
039: * obtain value to match against.
040: *
041: * <p><b>Global and local configuration</b></p>
042: * <table border="1">
043: * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
044: * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
045: * </table>
046: *
047: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
048: * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
049: * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
050: * @version CVS $Id: CachingWildcardMatcher.java 433543 2006-08-22 06:22:54Z crossley $
051: */
052: public class CachingWildcardMatcher extends AbstractWildcardMatcher
053: implements Configurable, Initializable, Composable, Disposable {
054:
055: /** The component manager instance */
056: protected ComponentManager manager;
057:
058: private String defaultParam;
059: private String defaultInput = "request-param"; // default to request parameters
060: private Configuration inputConf = null; // will become an empty configuration object
061: // during configure() so why bother here...
062: String INPUT_MODULE_ROLE = InputModule.ROLE;
063: String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE + "Selector";
064:
065: private boolean initialized = false;
066: private InputModule input = null;
067: private ComponentSelector inputSelector = null;
068:
069: /**
070: * Set the current <code>ComponentManager</code> instance used by this
071: * <code>Composable</code>.
072: */
073: public void compose(ComponentManager manager)
074: throws ComponentException {
075:
076: this .manager = manager;
077: }
078:
079: public void configure(Configuration config)
080: throws ConfigurationException {
081:
082: this .defaultParam = config.getChild("parameter-name").getValue(
083: null);
084: this .inputConf = config.getChild("input-module");
085: this .defaultInput = this .inputConf.getAttribute("name",
086: this .defaultInput);
087: }
088:
089: public void initialize() {
090:
091: try {
092: // obtain input module
093: this .inputSelector = (ComponentSelector) this .manager
094: .lookup(INPUT_MODULE_SELECTOR);
095: if (this .defaultInput != null
096: && this .inputSelector != null
097: && this .inputSelector
098: .hasComponent(this .defaultInput)) {
099: this .input = (InputModule) this .inputSelector
100: .select(this .defaultInput);
101: if (!(this .input instanceof ThreadSafe && this .inputSelector instanceof ThreadSafe)) {
102: this .inputSelector.release(this .input);
103: this .manager.release(this .inputSelector);
104: this .input = null;
105: this .inputSelector = null;
106: }
107: this .initialized = true;
108: } else {
109: if (getLogger().isErrorEnabled())
110: getLogger()
111: .error(
112: "A problem occurred setting up '"
113: + this .defaultInput
114: + "': Selector is "
115: + (this .inputSelector != null ? "not "
116: : "")
117: + "null, Component is "
118: + (this .inputSelector != null
119: && this .inputSelector
120: .hasComponent(this .defaultInput) ? "known"
121: : "unknown"));
122: }
123: } catch (Exception e) {
124: if (getLogger().isWarnEnabled())
125: getLogger().warn(
126: "A problem occurred setting up '"
127: + this .defaultInput + "': "
128: + e.getMessage());
129: }
130: }
131:
132: public void dispose() {
133:
134: if (!this .initialized)
135: if (getLogger().isErrorEnabled())
136: getLogger().error("Uninitialized Component! FAILING");
137: else if (this .inputSelector != null) {
138: if (this .input != null)
139: this .inputSelector.release(this .input);
140: this .manager.release(this .inputSelector);
141: }
142: }
143:
144: protected String getMatchString(Map objectModel,
145: Parameters parameters) {
146:
147: String paramName = parameters.getParameter("parameter-name",
148: this .defaultParam);
149: String inputName = parameters.getParameter("input-module",
150: this .defaultInput);
151:
152: if (!this .initialized) {
153: if (getLogger().isErrorEnabled())
154: getLogger().error("Uninitialized Component! FAILING");
155: return null;
156: }
157: if (paramName == null) {
158: if (getLogger().isWarnEnabled())
159: getLogger().warn(
160: "No parameter name given. Trying to Continue");
161: }
162: if (inputName == null) {
163: if (getLogger().isWarnEnabled())
164: getLogger().warn("No input module given. FAILING");
165: return null;
166: }
167:
168: Object result = null;
169:
170: if (this .input != null && inputName.equals(this .defaultInput)) {
171: // input module is thread safe
172: // thus we still have a reference to it
173: try {
174: if (this .input != null) {
175: result = this .input.getAttribute(paramName,
176: this .inputConf, objectModel);
177: }
178: } catch (Exception e) {
179: if (getLogger().isWarnEnabled())
180: getLogger().warn(
181: "A problem occurred acquiring Parameter '"
182: + paramName + "' from '"
183: + inputName + "': "
184: + e.getMessage());
185: }
186: } else {
187: // input was not thread safe
188: // so acquire it again
189: ComponentSelector iputSelector = null;
190: InputModule iput = null;
191: try {
192: // obtain input module
193: iputSelector = (ComponentSelector) this .manager
194: .lookup(INPUT_MODULE_SELECTOR);
195: if (iputSelector != null
196: && iputSelector.hasComponent(inputName)) {
197: iput = (InputModule) iputSelector.select(inputName);
198: }
199: if (iput != null) {
200: result = iput.getAttribute(paramName,
201: this .inputConf, objectModel);
202: }
203: } catch (Exception e) {
204: if (getLogger().isWarnEnabled())
205: getLogger().warn(
206: "A problem occurred acquiring Parameter '"
207: + paramName + "' from '"
208: + inputName + "': "
209: + e.getMessage());
210: } finally {
211: // release components
212: if (iputSelector != null) {
213: if (iput != null)
214: iputSelector.release(iput);
215: this .manager.release(iputSelector);
216: }
217: }
218: }
219:
220: if (result instanceof String) {
221: return (String) result;
222: } else {
223: return result.toString();
224: }
225: }
226: }
|