KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > variables > PreparedVariableResolver


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.components.variables;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.apache.avalon.framework.activity.Disposable;
22 import org.apache.avalon.framework.configuration.ConfigurationException;
23 import org.apache.avalon.framework.context.Context;
24 import org.apache.avalon.framework.service.ServiceException;
25 import org.apache.avalon.framework.service.ServiceManager;
26 import org.apache.avalon.framework.service.ServiceSelector;
27 import org.apache.avalon.framework.thread.ThreadSafe;
28 import org.apache.cocoon.components.ContextHelper;
29 import org.apache.cocoon.components.modules.input.InputModule;
30 import org.apache.cocoon.sitemap.PatternException;
31
32 /**
33  * Prepared implementation of {@link VariableResolver} for fast evaluation.
34  *
35  * @author <a HREF="mailto:sylvain@apache.org">Sylvain Wallez</a>
36  * @author <a HREF="mailto:tcurdt@apache.org">Torsten Curdt</a>
37  * @author <a HREF="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
38  * @version CVS $Id: PreparedVariableResolver.java 148910 2005-01-28 18:19:44Z cziegeler $
39  */

40 public class PreparedVariableResolver
41     extends NOPVariableResolver
42     implements Disposable {
43     
44     protected ServiceManager manager;
45     protected ServiceSelector selector;
46     protected Context context;
47         
48     protected List JavaDoc items = new ArrayList JavaDoc();
49
50     // Special constants used for levels
51
static final int LITERAL = -2;
52     static final int THREADSAFE_MODULE = -3;
53     static final int STATEFUL_MODULE = -4;
54
55     private static final Integer JavaDoc LITERAL_OBJ = new Integer JavaDoc(LITERAL);
56     private static final Integer JavaDoc THREADSAFE_MODULE_OBJ = new Integer JavaDoc(THREADSAFE_MODULE);
57     private static final Integer JavaDoc STATEFUL_MODULE_OBJ = new Integer JavaDoc(STATEFUL_MODULE);
58     
59     public PreparedVariableResolver(String JavaDoc expr, ServiceManager manager, Context context)
60     throws PatternException {
61         
62         super(null);
63         this.expression = expr;
64         this.manager = manager;
65         this.context = context;
66                 
67         int length = expr.length();
68         int prev = 0; // position after last closing brace
69

70         compile : while(prev < length) {
71             // find next unescaped '{'
72
int pos = prev;
73             while(pos < length &&
74                   (pos = expr.indexOf('{', pos)) != -1 &&
75                   (pos != 0 && expr.charAt(pos - 1) == '\\')) {
76                 pos++;
77             }
78
79             if (pos >= length || pos == -1) {
80                 // no more braces : add ending literal
81
if (prev < length) {
82                     addLiteral(expr.substring(prev));
83                 }
84                 break compile;
85             }
86
87             // Pass closing brace
88
pos++;
89
90             // Add litteral strings between closing and next opening brace
91
if (prev < pos-1) {
92                 addLiteral(expr.substring(prev, pos - 1));
93             }
94
95             int end = expr.indexOf('}', pos);
96             if (end == -1) {
97                 throw new PatternException("Unmatched '{' in " + expr);
98             }
99
100             int colon = expr.indexOf(':', pos);
101             if (colon != -1 && colon < end) {
102                     
103                 String JavaDoc module = expr.substring(pos, colon);
104                 String JavaDoc variable = expr.substring(colon + 1, end);
105
106                 // Module used
107
addModuleVariable(module, variable);
108             } else {
109                 throw new PatternException("Unknown variable format " + expr.substring(pos, end));
110             }
111
112             prev = end + 1;
113         }
114     }
115     
116     protected void addLiteral(String JavaDoc litteral) {
117         this.items.add(LITERAL_OBJ);
118         this.items.add(litteral);
119     }
120     
121
122     protected void addModuleVariable(String JavaDoc moduleName, String JavaDoc variable) throws PatternException {
123         if (this.selector == null) {
124             try {
125                 // First access to a module : lookup selector
126
this.selector = (ServiceSelector)this.manager.lookup(InputModule.ROLE + "Selector");
127             } catch(ServiceException ce) {
128                 throw new PatternException("Cannot access input modules selector", ce);
129             }
130         }
131         
132         // Get the module
133
InputModule module;
134         try {
135             module = (InputModule)this.selector.select(moduleName);
136         } catch(ServiceException ce) {
137             throw new PatternException("Cannot get InputModule named '" + moduleName +
138                 "' in expression '" + this.expression + "'", ce);
139         }
140         
141         // Is this module threadsafe ?
142
if (module instanceof ThreadSafe) {
143             this.items.add(THREADSAFE_MODULE_OBJ);
144             this.items.add(module);
145             this.items.add(variable);
146         } else {
147             // Statefull module : release it
148
this.selector.release(module);
149             this.items.add(STATEFUL_MODULE_OBJ);
150             this.items.add(moduleName);
151             this.items.add(variable);
152         }
153     }
154     
155     public String JavaDoc resolve()
156     throws PatternException {
157
158         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
159         
160         for (int i = 0; i < this.items.size(); i++) {
161             int type = ((Integer JavaDoc)this.items.get(i)).intValue();
162             
163             switch(type) {
164                 case LITERAL :
165                     result.append(items.get(++i));
166                 break;
167
168                 case THREADSAFE_MODULE :
169                 {
170                     InputModule module = (InputModule)items.get(++i);
171                     String JavaDoc variable = (String JavaDoc)items.get(++i);
172                     
173                     try {
174                         Object JavaDoc value = module.getAttribute(variable, null, ContextHelper.getObjectModel(this.context));
175                         
176                         if (value != null) {
177                             result.append(value);
178                         }
179
180                     } catch(ConfigurationException confEx) {
181                         throw new PatternException("Cannot get variable '" + variable +
182                             "' in expression '" + this.expression + "'", confEx);
183                     }
184                 }
185                 break;
186                 
187                 case STATEFUL_MODULE :
188                 {
189                     InputModule module = null;
190                     String JavaDoc moduleName = (String JavaDoc)items.get(++i);
191                     String JavaDoc variableName = (String JavaDoc)items.get(++i);
192                     try {
193                         module = (InputModule)this.selector.select(moduleName);
194                         
195                         Object JavaDoc value = module.getAttribute(variableName, null, ContextHelper.getObjectModel(this.context));
196                         
197                         if (value != null) {
198                             result.append(value);
199                         }
200                         
201                     } catch(ServiceException compEx) {
202                         throw new PatternException("Cannot get module '" + moduleName +
203                             "' in expression '" + this.expression + "'", compEx);
204                             
205                     } catch(ConfigurationException confEx) {
206                         throw new PatternException("Cannot get variable '" + variableName +
207                             "' in expression '" + this.expression + "'", confEx);
208                             
209                     } finally {
210                         this.selector.release(module);
211                     }
212                 }
213                 break;
214             }
215         }
216         
217         return result.toString();
218         
219     }
220     
221     /* (non-Javadoc)
222      * @see org.apache.avalon.framework.activity.Disposable#dispose()
223      */

224     public void dispose() {
225         if (this.selector != null) {
226             for (int i = 0; i < this.items.size(); i++) {
227                 int type = ((Integer JavaDoc) this.items.get(i)).intValue();
228
229                 switch (type) {
230                     case LITERAL:
231                         i++; // literal string
232
break;
233
234                     case THREADSAFE_MODULE:
235                         i++; // module
236
this.selector.release(this.items.get(i));
237                         i++; // variable
238
break;
239
240                     case STATEFUL_MODULE:
241                         i += 2; // module name, variable
242
break;
243
244                     default:
245                 }
246             }
247             this.manager.release(this.selector);
248             this.selector = null;
249             this.manager = null;
250         }
251     }
252 }
253
Popular Tags