1 25 package org.archive.crawler.deciderules; 26 27 import java.io.File ; 28 import java.io.IOException ; 29 import java.util.Collections ; 30 import java.util.HashMap ; 31 import java.util.Map ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 35 import org.archive.crawler.settings.SimpleType; 36 import org.archive.crawler.settings.Type; 37 38 import bsh.EvalError; 39 import bsh.Interpreter; 40 41 42 56 public class BeanShellDecideRule extends DecideRule { 57 58 private static final long serialVersionUID = -8433859929199308527L; 59 60 private static final Logger logger = 61 Logger.getLogger(BeanShellDecideRule.class.getName()); 62 63 64 public final static String ATTR_SCRIPT_FILE = "script-file"; 65 66 68 public final static String ATTR_ISOLATE_THREADS = "isolate-threads"; 69 70 protected ThreadLocal <Interpreter> threadInterpreter = 71 new ThreadLocal <Interpreter>();; 72 protected Interpreter sharedInterpreter; 73 public Map <Object ,Object > sharedMap = 74 Collections.synchronizedMap(new HashMap <Object ,Object >()); 75 protected boolean initialized = false; 76 77 public BeanShellDecideRule(String name) { 78 super(name); 79 setDescription("BeanShellDecideRule. Runs the BeanShell script " + 80 "source (supplied via a file path) against " + 81 "the current URI. Source should define a script method " + 82 "'decisionFor(object)' which will be passed the object" + 83 "to be evaluated and returns one of self.ACCEPT, " + 84 "self.REJECT, or self.PASS. " + 85 "The script may access this BeanShellDecideRule via" + 86 "the 'self' variable and the CrawlController via the " + 87 "'controller' variable. Runs the groovy script source " + 88 "(supplied via a file path) against the " + 89 "current URI."); 90 Type t = addElementToDefinition(new SimpleType(ATTR_SCRIPT_FILE, 91 "BeanShell script file", "")); 92 t.setOverrideable(false); 93 t = addElementToDefinition(new SimpleType(ATTR_ISOLATE_THREADS, 94 "Whether each ToeThread should get its own independent " + 95 "script context, or they should share synchronized access " + 96 "to one context. Default is true, meaning each threads " + 97 "gets its own isolated context.", true)); 98 t.setOverrideable(false); 99 } 100 101 public synchronized Object decisionFor(Object object) { 102 Interpreter interpreter = getInterpreter(); 105 synchronized(interpreter) { 106 try { 109 interpreter.set("object",object); 110 return interpreter.eval("decisionFor(object)"); 111 } catch (EvalError e) { 112 e.printStackTrace(); 114 return PASS; 115 } 116 } 117 } 118 119 124 protected Interpreter getInterpreter() { 125 if(sharedInterpreter==null 126 && !(Boolean )getUncheckedAttribute(null,ATTR_ISOLATE_THREADS)) { 127 sharedInterpreter = newInterpreter(); 129 } 130 if(sharedInterpreter!=null) { 131 return sharedInterpreter; 132 } 133 Interpreter interpreter = threadInterpreter.get(); 134 if(interpreter==null) { 135 interpreter = newInterpreter(); 136 threadInterpreter.set(interpreter); 137 } 138 return interpreter; 139 } 140 141 148 protected Interpreter newInterpreter() { 149 Interpreter interpreter = new Interpreter(); 150 try { 151 interpreter.set("self", this); 152 interpreter.set("controller", getController()); 153 154 String filePath = (String ) getUncheckedAttribute(null, ATTR_SCRIPT_FILE); 155 if(filePath.length()>0) { 156 try { 157 File file = getSettingsHandler().getPathRelativeToWorkingDirectory(filePath); 158 interpreter.source(file.getPath()); 159 } catch (IOException e) { 160 logger.log(Level.SEVERE,"unable to read script file",e); 161 } 162 } 163 } catch (EvalError e) { 164 e.printStackTrace(); 166 } 167 168 return interpreter; 169 } 170 171 172 176 public void kickUpdate() { 177 if((Boolean )getUncheckedAttribute(null,ATTR_ISOLATE_THREADS)) { 180 sharedInterpreter = null; 181 threadInterpreter = new ThreadLocal <Interpreter>(); 182 } else { 183 sharedInterpreter = newInterpreter(); 184 threadInterpreter = null; 185 } 186 } 187 } 188 | Popular Tags |