1 16 package scriptella.driver.text; 17 18 import scriptella.expression.PropertiesSubstitutor; 19 import scriptella.spi.AbstractConnection; 20 import scriptella.spi.ParametersCallback; 21 import scriptella.spi.QueryCallback; 22 import scriptella.util.ExceptionUtils; 23 import scriptella.util.IOUtils; 24 import scriptella.util.StringUtils; 25 26 import java.io.BufferedReader ; 27 import java.io.Closeable ; 28 import java.io.IOException ; 29 import java.io.Reader ; 30 import java.util.ArrayList ; 31 import java.util.List ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import java.util.regex.Matcher ; 35 import java.util.regex.Pattern ; 36 37 74 class TextQueryExecutor implements ParametersCallback, Closeable { 75 private static final Logger LOG = Logger.getLogger(TextQueryExecutor.class.getName()); 76 private final ParametersCallback params; 77 private final PropertiesSubstitutor ps; 78 private Pattern [] query; 79 private BufferedReader reader; 80 private Matcher result; 81 private boolean trim; 82 private static final String COLUMN_PREFIX = "column"; 83 84 public TextQueryExecutor(final Reader queryReader, final boolean trim, final Reader in, final ParametersCallback parentParametersCallback) { 85 if (queryReader == null) { 86 throw new IllegalArgumentException ("Query cannot be null"); 87 } 88 this.trim = trim; 89 this.params = parentParametersCallback; 90 ps = new PropertiesSubstitutor(params); 91 BufferedReader r = IOUtils.asBuffered(queryReader); 94 List <Pattern > result = new ArrayList <Pattern >(); 95 try { 96 for (String s; (s = r.readLine()) != null;) { 97 if (trim) { 98 s = s.trim(); 99 } 100 s = ps.substitute(s); 101 if (s.length() > 0) { try { 103 result.add(Pattern.compile(s, Pattern.CASE_INSENSITIVE)); 104 } catch (Exception e) { 105 throw new TextProviderException("Specified query is not a valid regex: " + s, e); 106 } 107 } 108 } 109 } catch (IOException e) { 110 throw new TextProviderException("Unable to read query content", e); 111 } finally { 112 IOUtils.closeSilently(r); 113 } 114 if (result.isEmpty()) { 115 LOG.fine("Empty query matches all lines"); 116 result.add(Pattern.compile(".*")); 117 } 118 query = result.toArray(new Pattern [result.size()]); 119 reader = IOUtils.asBuffered(in); 120 121 } 122 123 129 public void execute(final QueryCallback qc, AbstractConnection.StatementCounter counter) { 130 int qCount = query.length; 131 try { 132 Matcher [] matchers = new Matcher [qCount]; 133 for (String line; (line = reader.readLine()) != null;) { 134 if (trim) { 135 line = line.trim(); 136 } 137 for (int i = 0; i < qCount; i++) { 138 Matcher m = matchers[i]; 139 if (m == null) { m = query[i].matcher(line); 141 matchers[i] = m; 142 } else { m.reset(line); 144 } 145 if (m.matches()) { 146 if (LOG.isLoggable(Level.FINE)) { 147 LOG.info("Pattern matched: " + m); 148 } 149 result = m; 150 qc.processRow(this); 151 } 152 } 153 } 154 } catch (IOException e) { 155 throw new TextProviderException("Unable to read a text file", e); 156 } 157 counter.statements+=qCount; 158 } 159 160 161 168 public Object getParameter(final String name) { 169 String str = name; 170 if (str != null && str.startsWith(COLUMN_PREFIX)) { 171 str = name.substring(COLUMN_PREFIX.length()); 172 } 173 if (StringUtils.isDecimalInt(str)) { 174 try { 175 int ind = Integer.parseInt(str); 176 if (ind >= 0 && ind <= result.groupCount()) { 177 return result.group(ind); 178 } 179 } catch (NumberFormatException e) { 180 ExceptionUtils.ignoreThrowable(e); 181 } 182 } 183 return params.getParameter(name); 184 } 185 186 public void close() throws IOException { 187 IOUtils.closeSilently(reader); 188 reader = null; 189 } 190 } 191 | Popular Tags |