1 16 package org.apache.cocoon.components.variables; 17 18 import java.util.ArrayList ; 19 import java.util.List ; 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 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 items = new ArrayList (); 49 50 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 LITERAL_OBJ = new Integer (LITERAL); 56 private static final Integer THREADSAFE_MODULE_OBJ = new Integer (THREADSAFE_MODULE); 57 private static final Integer STATEFUL_MODULE_OBJ = new Integer (STATEFUL_MODULE); 58 59 public PreparedVariableResolver(String 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; 70 compile : while(prev < length) { 71 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 if (prev < length) { 82 addLiteral(expr.substring(prev)); 83 } 84 break compile; 85 } 86 87 pos++; 89 90 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 module = expr.substring(pos, colon); 104 String variable = expr.substring(colon + 1, end); 105 106 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 litteral) { 117 this.items.add(LITERAL_OBJ); 118 this.items.add(litteral); 119 } 120 121 122 protected void addModuleVariable(String moduleName, String variable) throws PatternException { 123 if (this.selector == null) { 124 try { 125 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 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 if (module instanceof ThreadSafe) { 143 this.items.add(THREADSAFE_MODULE_OBJ); 144 this.items.add(module); 145 this.items.add(variable); 146 } else { 147 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 resolve() 156 throws PatternException { 157 158 StringBuffer result = new StringBuffer (); 159 160 for (int i = 0; i < this.items.size(); i++) { 161 int type = ((Integer )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 variable = (String )items.get(++i); 172 173 try { 174 Object 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 moduleName = (String )items.get(++i); 191 String variableName = (String )items.get(++i); 192 try { 193 module = (InputModule)this.selector.select(moduleName); 194 195 Object 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 224 public void dispose() { 225 if (this.selector != null) { 226 for (int i = 0; i < this.items.size(); i++) { 227 int type = ((Integer ) this.items.get(i)).intValue(); 228 229 switch (type) { 230 case LITERAL: 231 i++; break; 233 234 case THREADSAFE_MODULE: 235 i++; this.selector.release(this.items.get(i)); 237 i++; break; 239 240 case STATEFUL_MODULE: 241 i += 2; 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 |