All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scriptella.driver.text.TextQueryExecutor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2006-2010 The Scriptella Project Team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package scriptella.driver.text;

import scriptella.expression.LineIterator;
import scriptella.expression.PropertiesSubstitutor;
import scriptella.spi.AbstractConnection;
import scriptella.spi.ParametersCallback;
import scriptella.spi.QueryCallback;
import scriptella.util.ExceptionUtils;
import scriptella.util.IOUtils;
import scriptella.util.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class executes a regex query over a text file content.
 * 

The query has a standard regex syntax. * Matching is performed for each line of the text file. *

Example:

* Query: .*;(2\d+);.*
* Text File: * *
 * 1;100;record 1
 * 2;200;record 2
 * 3;250;record 3
 * 
*
* As the result of the query execution the following result set is produced: * * * * * * * * * * * * * * * * *
Column name/
row number
01
12;200;record 2200
23;250;record 3250
* Where column name corresponds to the matched regex group name. * * @author Fyodor Kupolov * @version 1.0 */ class TextQueryExecutor implements ParametersCallback { private static final Logger LOG = Logger.getLogger(TextQueryExecutor.class.getName()); private static final String COLUMN_PREFIX = "column"; private final PropertiesSubstitutor ps; private Pattern[] query; private Matcher result; private TextConnectionParameters textParams; public TextQueryExecutor(final Reader queryReader, final PropertiesSubstitutor substitutor, final TextConnectionParameters textParams) { this.textParams = textParams; ps = substitutor; //Compiles patterns loaded from specified reader. //Patterns are read line-by-line. BufferedReader r = IOUtils.asBuffered(queryReader); List result = new ArrayList(); try { for (String s; (s = r.readLine()) != null;) { s = s.trim(); s = ps.substitute(s); if (s.length() > 0) { //Not empty string try { result.add(Pattern.compile(s, Pattern.CASE_INSENSITIVE)); } catch (Exception e) { throw new TextProviderException("Specified query is not a valid regex: " + s, e); } } } } catch (IOException e) { throw new TextProviderException("Unable to read query content", e); } finally { IOUtils.closeSilently(r); } if (result.isEmpty()) { LOG.fine("Empty query matches all lines"); result.add(Pattern.compile(".*")); } query = result.toArray(new Pattern[result.size()]); } /** * Executes a query and iterates the resultset using the callback. * * @param qc callback to notify on each row. * @param counter statements counter. */ public void execute(Reader reader, final QueryCallback qc, AbstractConnection.StatementCounter counter) { int qCount = query.length; Matcher[] matchers = new Matcher[qCount]; LineIterator it = new LineIterator(reader, ps, textParams.isTrimLines()); //Skip a specified number of lines for (int i = textParams.getSkipLines(); i > 0 && it.hasNext(); i--) { it.next(); } while (it.hasNext()) { String line = it.next(); for (int i = 0; i < qCount; i++) { Matcher m = matchers[i]; if (m == null) { //First time initialization m = query[i].matcher(line); matchers[i] = m; } else { //Reuse matcher for better performance m.reset(line); } if (m.find()) { if (LOG.isLoggable(Level.FINE)) { LOG.info("Pattern matched: " + m); } result = m; qc.processRow(this); } } } counter.statements += qCount; } /** * Returns the value of the named parameter. *

Use index of the captured group to obtain the value of the matched substring. * * @param name parameter name. * @return parameter value. */ public Object getParameter(final String name) { String str = name; if (str != null && str.startsWith(COLUMN_PREFIX)) { str = name.substring(COLUMN_PREFIX.length()); } if (StringUtils.isDecimalInt(str)) { try { int ind = Integer.parseInt(str); if (ind >= 0 && ind <= result.groupCount()) { final String s = result.group(ind); return textParams.getPropertyFormatter().parse(name, s); } } catch (NumberFormatException e) { ExceptionUtils.ignoreThrowable(e); } } return ps.getParameters().getParameter(name); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy