001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.qbean; 020 021import bsh.EvalError; 022import bsh.Interpreter; 023import org.jdom2.Element; 024import org.jpos.core.ConfigurationException; 025import org.jpos.q2.QBeanSupport; 026import org.jpos.space.Space; 027import org.jpos.space.SpaceError; 028import org.jpos.space.SpaceFactory; 029import org.jpos.util.NameRegistrar; 030 031import java.io.IOException; 032import java.util.Iterator; 033 034/** 035 * QBean that adapts a {@link Space} for scripted access via BeanShell, allowing 036 * incoming/outgoing operations to be intercepted by configured BSH snippets. 037 */ 038@SuppressWarnings("unchecked") 039public class SpaceLet extends QBeanSupport implements Space { 040 /** Default constructor; no instance state to initialise. */ 041 public SpaceLet() {} 042 Space sp; 043 String uri; 044 String outScript, outSource; 045 String pushScript, pushSource; 046 String inScript, inSource; 047 String rdScript, rdSource; 048 String putScript, putSource; 049 050 public void initService() throws ConfigurationException { 051 Element config = getPersist (); 052 grabSpace (config.getChild ("space")); 053 initSpace (config.getChild ("init")); 054 055 String name = getName(); 056 if ("spacelet".equals (name)) 057 name = "default"; 058 uri = "spacelet:" + name; 059 060 Element e = config.getChild ("out"); 061 outScript = getScript (e); 062 if (e != null) 063 outSource = e.getAttributeValue ("source"); 064 065 e = config.getChild ("push"); 066 pushScript = getScript (e); 067 if (e != null) 068 pushSource = e.getAttributeValue ("source"); 069 070 e = config.getChild ("in"); 071 inScript = getScript (e); 072 if (e != null) 073 inSource = e.getAttributeValue ("source"); 074 075 e = config.getChild ("rd"); 076 rdScript = getScript (e); 077 if (e != null) 078 rdSource = e.getAttributeValue ("source"); 079 080 e = config.getChild ("put"); 081 putScript = getScript (e); 082 if (e != null) 083 putSource = e.getAttributeValue ("source"); 084 085 } 086 public void startService() { 087 NameRegistrar.register (uri, this); 088 089 Iterator iter = getPersist().getChildren("run").iterator(); 090 while (iter.hasNext ()) 091 launch ((Element) iter.next ()); 092 } 093 public void stopService() { 094 NameRegistrar.unregister (uri); 095 } 096 public void out (Object key, Object value) { 097 try { 098 Interpreter bsh = initInterpreter (key, value); 099 synchronized (sp) { 100 if (!eval (bsh, outScript, outSource)) 101 sp.out (key, value); 102 } 103 } catch (Throwable t) { 104 throw new SpaceError (t); 105 } 106 } 107 public void out (Object key, Object value, long timeout) { 108 try { 109 Interpreter bsh = initInterpreter (key, value, timeout); 110 synchronized (sp) { 111 if (!eval (bsh, outScript, outSource)) 112 sp.out (key, value, timeout); 113 } 114 } catch (Throwable t) { 115 throw new SpaceError (t); 116 } 117 } 118 public void push (Object key, Object value) { 119 try { 120 Interpreter bsh = initInterpreter (key, value); 121 synchronized (sp) { 122 if (!eval (bsh, pushScript, pushSource)) 123 sp.out (key, value); 124 } 125 } catch (Throwable t) { 126 throw new SpaceError (t); 127 } 128 } 129 public void push (Object key, Object value, long timeout) { 130 try { 131 Interpreter bsh = initInterpreter (key, value, timeout); 132 synchronized (sp) { 133 if (!eval (bsh, pushScript, pushSource)) 134 sp.out (key, value, timeout); 135 } 136 } catch (Throwable t) { 137 throw new SpaceError (t); 138 } 139 } 140 public void put (Object key, Object value) { 141 try { 142 Interpreter bsh = initInterpreter (key, value); 143 synchronized (sp) { 144 if (!eval (bsh, putScript, putSource)) 145 sp.put (key, value); 146 } 147 } catch (Throwable t) { 148 throw new SpaceError (t); 149 } 150 } 151 public void put (Object key, Object value, long timeout) { 152 try { 153 Interpreter bsh = initInterpreter (key, value, timeout); 154 synchronized (sp) { 155 if (!eval (bsh, putScript, putSource)) 156 sp.out (key, value, timeout); 157 } 158 } catch (Throwable t) { 159 throw new SpaceError (t); 160 } 161 } 162 163 164 public Object in (Object key) { 165 try { 166 Interpreter bsh = initInterpreter (key); 167 synchronized (sp) { 168 if (eval (bsh, inScript, inSource)) { 169 return bsh.get ("value"); 170 } else { 171 return sp.in (key); 172 } 173 } 174 } catch (Throwable t) { 175 throw new SpaceError (t); 176 } 177 } 178 public Object rd (Object key) { 179 try { 180 Interpreter bsh = initInterpreter (key); 181 synchronized (sp) { 182 if (eval (bsh, rdScript, rdSource)) { 183 return bsh.get ("value"); 184 } else { 185 return sp.rd (key); 186 } 187 } 188 } catch (Throwable t) { 189 throw new SpaceError (t); 190 } 191 } 192 public Object in (Object key, long timeout) { 193 try { 194 Interpreter bsh = initInterpreter (key, timeout); 195 synchronized (sp) { 196 if (eval (bsh, inScript, inSource)) { 197 return bsh.get ("value"); 198 } else { 199 return sp.in (key, timeout); 200 } 201 } 202 } catch (Throwable t) { 203 throw new SpaceError (t); 204 } 205 } 206 public Object rd (Object key, long timeout) { 207 try { 208 Interpreter bsh = initInterpreter (key, timeout); 209 synchronized (sp) { 210 if (eval (bsh, rdScript, rdSource)) { 211 return bsh.get ("value"); 212 } else { 213 return sp.rd (key, timeout); 214 } 215 } 216 } catch (Throwable t) { 217 throw new SpaceError (t); 218 } 219 } 220 public Object inp (Object key) { 221 try { 222 Interpreter bsh = initInterpreter (key); 223 bsh.set ("probe", true); 224 synchronized (sp) { 225 if (eval (bsh, inScript, inSource)) { 226 return bsh.get ("value"); 227 } else { 228 return sp.inp (key); 229 } 230 } 231 } catch (Throwable t) { 232 throw new SpaceError (t); 233 } 234 } 235 public Object rdp (Object key) { 236 try { 237 Interpreter bsh = initInterpreter (key); 238 bsh.set ("probe", true); 239 synchronized (sp) { 240 if (eval (bsh, rdScript, rdSource)) { 241 return bsh.get ("value"); 242 } else { 243 return sp.rdp (key); 244 } 245 } 246 } catch (Throwable t) { 247 throw new SpaceError (t); 248 } 249 } 250 public boolean existAny (Object[] keys) { 251 return sp.existAny (keys); 252 } 253 public boolean existAny (Object[] keys, long timeout) { 254 return sp.existAny (keys, timeout); 255 } 256 private void grabSpace (Element e) { 257 sp = SpaceFactory.getSpace (e != null ? e.getText() : ""); 258 } 259 private String getScript (Element e) { 260 return e == null ? null : e.getText(); 261 } 262 public void nrd (Object key) { 263 sp.nrd(key); 264 } 265 public Object nrd (Object key, long timeout) { 266 return sp.nrd(key, timeout); 267 } 268 private void launch (Element e) { 269 // final Interpreter bsh = initInterpreter (); 270 final String script = e.getText(); 271 final String source = e.getAttributeValue ("source"); 272 273 new Thread ("SpaceLet-launch") { 274 public void run () { 275 try { 276 eval (initInterpreter(), script, source); 277 } catch (Throwable t) { 278 getLog().warn (t); 279 } 280 } 281 }.start (); 282 } 283 private void initSpace (Element e) throws ConfigurationException { 284 if (e == null) 285 return; 286 287 try { 288 eval ( 289 initInterpreter(), 290 e.getText(), 291 e.getAttributeValue ("source") 292 ); 293 } catch (Throwable t) { 294 throw new ConfigurationException (t); 295 } 296 } 297 private Interpreter initInterpreter () throws EvalError { 298 Interpreter bsh = new Interpreter (); 299 bsh.set ("sp", sp); 300 bsh.set ("spacelet", this); 301 bsh.set ("log", getLog()); 302 return bsh; 303 } 304 private Interpreter initInterpreter (Object key) throws EvalError { 305 Interpreter bsh = initInterpreter (); 306 bsh.set ("key", key); 307 return bsh; 308 } 309 private Interpreter initInterpreter (Object key, Object value) 310 throws EvalError 311 { 312 Interpreter bsh = initInterpreter (key); 313 bsh.set ("value", value); 314 return bsh; 315 } 316 private Interpreter initInterpreter 317 (Object key, Object value, long timeout) 318 throws EvalError 319 { 320 Interpreter bsh = initInterpreter (key, value); 321 bsh.set ("timeout", timeout); 322 return bsh; 323 } 324 private Interpreter initInterpreter (Object key, long timeout) 325 throws EvalError 326 { 327 Interpreter bsh = initInterpreter (key); 328 bsh.set ("timeout", timeout); 329 return bsh; 330 } 331 private boolean eval (Interpreter bsh, String script, String source) 332 throws EvalError, IOException 333 { 334 boolean rc = false; 335 if (script != null) { 336 Object retValue = bsh.eval (script); 337 if (source != null) 338 retValue = bsh.source (source); 339 if (retValue instanceof Boolean) { 340 rc = (Boolean) retValue; 341 } 342 } 343 return rc; 344 } 345} 346