/*
* JOSSO: Java Open Single Sign-On
*
* Copyright 2004-2009, Atricore, Inc.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.josso.tooling.gshell.core.commands.utils;
import org.apache.geronimo.gshell.command.annotation.CommandComponent;
import org.apache.geronimo.gshell.clp.Argument;
import org.apache.geronimo.gshell.clp.Option;
import org.codehaus.plexus.util.StringUtils;
import org.josso.tooling.gshell.core.support.JOSSOCommandSupport;
import java.util.regex.Pattern;
import java.io.IOException;
import java.io.Reader;
@CommandComponent(id="utils:grep", description="Print lines matching a pattern")
public class GrepCommand extends JOSSOCommandSupport {
@Argument(required=true, description="Regular expression")
private String regex;
@Option(name="-n", aliases = { "--line-number" }, description="Prefix each line of output with the line number within its input file.")
private boolean lineNumber;
@Option(name = "-v", aliases = { "--invert-match" }, description = "Invert the sense of matching, to select non-matching lines.")
private boolean invertMatch;
@Option(name = "-w", aliases = { "--word-regexp" }, description = "Select only those lines containing matches that form whole " +
"words. The test is that the matching substring must either be " +
"at the beginning of the line, or preceded by a non-word constituent " +
"character. Similarly, it must be either at the end of " +
"the line or followed by a non-word constituent character. " +
"Word-constituent characters are letters, digits, and the underscore.")
private boolean wordRegexp;
@Option(name = "-x", aliases = { "--line-regexp" }, description = "Select only those matches that exactly match the whole line.")
private boolean lineRegexp;
protected Object doExecute() throws Exception {
String regexp = regex;
if (wordRegexp) {
regexp = "\\b" + regexp + "\\b";
}
if (lineRegexp) {
regexp = "^" + regexp + "$";
} else {
regexp = ".*" + regexp + ".*";
}
Pattern p = Pattern.compile(regexp);
try {
int lineno = 1;
String line;
while ((line = readLine(io.in)) != null) {
if (p.matcher(line).matches() ^ invertMatch) {
if (lineNumber) {
String gutter = StringUtils.leftPad(String.valueOf(lineno), 6);
io.out.print(gutter);
io.out.print(" ");
}
io.out.println(line);
lineno++;
}
}
} catch (IOException e) {
}
return null;
}
private String readLine(Reader in) throws IOException {
StringBuffer buf = new StringBuffer();
while (true) {
int i = in.read();
if (i == -1 && buf.length() == 0) {
throw new IOException("break");
}
if (i == -1 || i == '\n' || i == '\r') {
return buf.toString();
}
buf.append((char) i);
}
}
}