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

de.unkrig.zz.grep.AntTask Maven / Gradle / Ivy

The newest version!

/*
 * de.unkrig.grep - An advanced version of the UNIX GREP utility
 *
 * Copyright (c) 2011, Arno Unkrig
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
 * following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 *       following disclaimer in the documentation and/or other materials provided with the distribution.
 *    3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
 *       products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package de.unkrig.zz.grep;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.FileProvider;

import de.unkrig.commons.file.contentsprocessing.ContentsProcessor;
import de.unkrig.commons.file.fileprocessing.FileProcessor;
import de.unkrig.commons.lang.protocol.ProducerWhichThrows;
import de.unkrig.commons.nullanalysis.Nullable;
import de.unkrig.commons.text.pattern.Glob;
import de.unkrig.commons.text.pattern.Pattern2;
import de.unkrig.zz.grep.Grep.Operation;

/**
 * Finds lines in files in directory trees, archives an compressed files by regular expressions.
 * 

* To use this task, add this to your ANT build script: *

*
{@code

 * }
*/ public class AntTask extends Task { private static final Logger LOGGER = Logger.getLogger(Task.class.getName()); private final Grep grep = new Grep(); @Nullable private File file; @Nullable private String path; @Nullable private String regex; @Nullable private Boolean caseSensitive; @Nullable private String property; private final List resourceCollections = new ArrayList(); // BEGIN CONFIGURATION SETTERS /** Another file that will be searched. */ public void setFile(File file) { this.file = file; } /** * Look into archive files, nested archives, compressed files and nested compressed contents iff * "format:path" matches the given glob. *

* The default is to look into any archive files, nested archives, compressed files and nested compressed * contents. *

* * @ant.valueExplanation format-glob:path-glob */ public void setLookInto(String value) { this.grep.setLookIntoFormat(Glob.compile(value, Pattern2.WILDCARD | Glob.INCLUDES_EXCLUDES)); } /** * The charset to use when reading files and nested contents. *

* Default is the "platform default encoding". *

* * @ant.valueExplanation charset */ public void setEncoding(String value) { this.grep.setCharset(Charset.forName(value)); } /** *
*
NORMAL
*
* For each match, print the file name, a colon, a space and the matched line. *
*
LIST
*
* For each match, print the file name. *
*
QUIET
*
* Do not print anything. *
*
*/ public void setOperation(Operation value) { this.grep.setOperation(value); } /** * Whether matching lines should be treated as non-matching, and vice versa. */ public void setInverted(boolean value) { this.grep.setInverted(value); } /** * Whether to disassemble Java class files on-the-fly before matching its contents. */ public void setDisassembleClassFiles(boolean value) { this.grep.setDisassembleClassFiles(value); } /** * Whether to include a constant pool dump, constant pool indexes, and hex dumps of all attributes in the * disassembly output. */ public void setDisassembleClassFilesVerbose(boolean value) { this.grep.setDisassembleClassFilesVerbose(value); } /** * Where to look for source files when disassembling .class files; {@code null} disables source file loading. Source * file loading is disabled by default. */ public void setDisassembleClassFilesSourceDirectory(@Nullable File value) { this.grep.setDisassembleClassFilesSourceDirectory(value); } /** * Whether to hide source line numbers in the Java class file disassembly. */ public void setDisassembleClassFilesButHideLines(boolean value) { this.grep.setDisassembleClassFilesButHideLines(value); } /** * Whether to remove local variable names from the Java class file disassembly. */ public void setDisassembleClassFilesButHideVars(boolean value) { this.grep.setDisassembleClassFilesButHideVars(value); } /** * Whether to use numeric labels ('#123') or symbolic labels /'L12') in the bytecode disassembly. */ public void setDisassembleClassFilesSymbolicLabels(boolean value) { this.grep.setDisassembleClassFilesSymbolicLabels(value); } /** * @deprecated Use {@link #setPath(String)} instead */ @Deprecated public void setName(String value) { this.setPath(value); } /** * Search for matches only in files / entries who's path match the glob. */ public void setPath(String pathGlob) { this.path = pathGlob; } /** * The regular expression to match each line of input against. */ public void setRegex(String regex) { this.regex = regex; } /** * Whether the {@link #setRegex(String)} should be applied case-sensitively. * * @ant.defaultValue true */ public void setCaseSensitive(boolean value) { this.caseSensitive = value; } /** * If set, then set the named property to "true" iff there is at least one match. */ public void setProperty(String propertyName) { this.property = propertyName; } /***/ public static class Element_path_regex_caseSensitive { // SUPPRESS CHECKSTYLE TypeName @Nullable private String path; @Nullable private String regex; private boolean caseSensitive = true; /** * @deprecated Use {@link #setPath(String)} instead */ @Deprecated public void setName(String value) { this.setPath(value); } /** * Search for matches only in files / entries who's path match the glob. */ public void setPath(String glob) { this.path = glob; } /** * The regular expression to match each line of input against. */ public void setRegex(String regex) { this.regex = regex; } /** * Whether the regex should be applied case-sensitively. * * @ant.defaultValue true */ public void setCaseSensitive(boolean value) { this.caseSensitive = value; } } /** * In addition to the search configured by {@link #setName(String)}, {@link #setRegex(String)} and {@link * #setCaseSensitive(boolean)} attributes of the task (explained above), execute another search. */ public void addConfiguredSearch(Element_path_regex_caseSensitive element) { if (this.path != null || this.regex != null || this.caseSensitive != null) { throw new BuildException( "'path=\"...\"', 'regex=\"...\"' and 'caseSensitive=\"...\"' are mutually exclusive " + "with '' subelements" ); } final String path = element.path; final String regex = element.regex; if (regex == null) throw new BuildException("Attribute 'regex' must be set"); this.grep.addSearch( path == null ? Glob.ANY : Glob.compile(path, Pattern2.WILDCARD | Glob.INCLUDES_EXCLUDES), regex, element.caseSensitive ); } /** Another set of files or directory trees to search. */ public void addConfigured(ResourceCollection value) { this.resourceCollections.add(value); } // END CONFIGURATION SETTERS /** * The ANT task "execute" method. * * @see Task#execute */ @Override public void execute() throws BuildException { try { this.execute2(); } catch (BuildException be) { throw be; } catch (Exception e) { throw new BuildException(e); } } private void execute2() throws Exception { { String regex = this.regex; String path = this.path; Boolean caseSensitive = this.caseSensitive; if (regex != null) { this.grep.addSearch( path == null ? Glob.ANY : Glob.compile(path, Pattern2.WILDCARD | Glob.INCLUDES_EXCLUDES), regex, caseSensitive == null ? true : caseSensitive ); } else if (path != null || caseSensitive != null) { throw new BuildException( "'path=\"...\"' and 'caseSensitive=\"...\"' don't make sense without 'regex=\"...\"'" ); } } ContentsProcessor contentsProcessor = this.grep.contentsProcessor(); FileProcessor fileProcessor = this.grep.fileProcessor( false // lookIntoDirectories We don't want directory traversal - ANT already did this for us ); // Process 'file="..."'. { File file = this.file; if (file != null) { AntTask.LOGGER.log(Level.CONFIG, "Grepping ''{0}''", file.getPath()); fileProcessor.process(file.getPath(), file); } } // Process resource collections. for (ResourceCollection resourceCollection : this.resourceCollections) { // Process each resource of each collection. for ( @SuppressWarnings("unchecked") Iterator it = resourceCollection.iterator(); it.hasNext(); ) { final Resource resource = it.next(); String path = resource.getName(); AntTask.LOGGER.log(Level.CONFIG, "Grepping ''{0}''", path); if (resource.isFilesystemOnly()) { // Grep file resource. fileProcessor.process(path, ((FileProvider) resource).getFile()); } else { // Grep non-file resource. InputStream is = resource.getInputStream(); try { long lastModified = resource.getLastModified(); Date lastModifiedDate = lastModified == 0 ? null : new Date(lastModified); contentsProcessor.process( path, // path is, // inputStream lastModifiedDate, // lastModifiedDate resource.getSize(), // size -1L, // crc32 new ProducerWhichThrows() { // opener @Override @Nullable public InputStream produce() throws IOException { return resource.getInputStream(); } } ); is.close(); } finally { try { is.close(); } catch (Exception e) {} } } } } if (this.property != null && this.grep.getLinesSelected()) { this.getProject().setProperty(this.property, "true"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy