alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

// $Header: /home/cvs/jakarta-jmeter/src/protocol/http/org/apache/jmeter/protocol/http/util/accesslog/LogFilter.java,v 1.10 2004/03/13 19:49:14 sebb Exp $
/*
 * Copyright 2003-2004 The Apache Software Foundation.
 *
 * 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 org.apache.jmeter.protocol.http.util.accesslog;

import java.util.ArrayList;

import org.apache.jmeter.junit.JMeterTestCase;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

/**
 * Description:
*
* LogFilter is a basic implementation of Filter * interface. This implementation will keep a * record of the filtered strings to avoid * repeating the process unnecessarily.

* The current implementation supports * replacing the file extension. The reason for * supporting this is from first hand experience * porting an existing website to Tomcat + JSP. * Later on we may want to provide the ability * to replace the whole filename. If the need * materializes, we can add it later.

* Example of how to use it is provided in the * main method. An example is provided below. *

*

 * testf = new LogFilter();
 * String[] incl = {"hello.html",
 *         "index.html",
 *         "/index.jsp"};
 * String[] thefiles = {"/test/hello.jsp",
 *         "/test/one/hello.html",
 *         "hello.jsp",
 *         "hello.htm",
 *         "/test/open.jsp",
 *         "/test/open.html",
 *         "/index.jsp",
 *         "/index.jhtml",
 *         "newindex.jsp",
 *         "oldindex.jsp",
 *         "oldindex1.jsp",
 *         "oldindex2.jsp",
 *         "oldindex3.jsp",
 *         "oldindex4.jsp",
 *         "oldindex5.jsp",
 *         "oldindex6.jsp",
 *         "/test/index.htm"};
 * testf.excludeFiles(incl);
 * System.out.println(" ------------ exclude test -------------");
 * for (int idx=0; idx < thefiles.length; idx++){
 * 	boolean fl = testf.isFiltered(thefiles[idx]);
 * 	String line = testf.filter(thefiles[idx]);
 * 	if (line != null){
 *         System.out.println("the file: "+ line);
 * 	}
 * }
 * 
* As a general note. Both isFiltered and filter() * have to be called. Calling either one will not * produce the desired result. isFiltered(string) * will tell you if a string should be filtered. * The second step is to filter the string, which * will return null if it is filtered and replace * any part of the string that should be replaced. *

* * @version $Revision: 1.10 $ last updated $Date: 2004/03/13 19:49:14 $ * Created on: Jun 26, 2003
*/ public class LogFilter implements Filter { /** protected members used by class to filter **/ protected boolean CHANGEEXT = false; protected String OLDEXT = null; protected String NEWEXT = null; protected String[] INCFILE = null; protected String[] EXCFILE = null; protected boolean FILEFILTER = false; protected boolean USEFILE = true; protected String[] INCPTRN = null; protected String[] EXCPTRN = null; protected boolean PTRNFILTER = false; protected ArrayList EXCPATTERNS = new ArrayList(); protected ArrayList INCPATTERNS = new ArrayList(); protected String NEWFILE = null; protected Perl5Matcher MATCHER = null; /** * The default constructor is empty */ public LogFilter() { super(); } /** * The method will replace the file extension * with the new one. You can either provide * the extension without the period ".", or * with. The method will check for period * and add it if it isn't present. * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#setReplaceExtension(java.lang.String, java.lang.String) */ public void setReplaceExtension(String oldext, String newext) { if (oldext != null && newext != null) { this.CHANGEEXT = true; if (oldext.indexOf(".") < 0 && newext.indexOf(".") < 0) { this.OLDEXT = "." + oldext; this.NEWEXT = "." + newext; } else { this.OLDEXT = oldext; this.NEWEXT = newext; } } } /** * Give the filter a list of files to include * @param filenames * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#includeFiles(java.lang.String[]) */ public void includeFiles(String[] filenames) { if (filenames != null && filenames.length > 0) { INCFILE = filenames; this.FILEFILTER = true; } } /** * Give the filter a list of files to exclude * @param filenames * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#excludeFiles(java.lang.String[]) */ public void excludeFiles(String[] filenames) { if (filenames != null && filenames.length > 0) { EXCFILE = filenames; this.FILEFILTER = true; } } /** * Give the filter a set of regular expressions * to filter with for inclusion. This method hasn't * been fully implemented and test yet. The * implementation is not complete. * @param regexp * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#includePattern(String[]) */ public void includePattern(String[] regexp) { if (regexp != null && regexp.length > 0) { INCPTRN = regexp; this.PTRNFILTER = true; // now we create the compiled pattern and // add it to the arraylist for (int idx = 0; idx < INCPTRN.length; idx++) { this.INCPATTERNS.add(this.createPattern(INCPTRN[idx])); } } } /** * Give the filter a set of regular expressions * to filter with for exclusion. This method hasn't * been fully implemented and test yet. The * implementation is not complete. * @param regexp * * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#excludePattern(String[]) */ public void excludePattern(String[] regexp) { if (regexp != null && regexp.length > 0) { EXCPTRN = regexp; this.PTRNFILTER = true; // now we create the compiled pattern and // add it to the arraylist for (int idx = 0; idx < EXCPTRN.length; idx++) { this.EXCPATTERNS.add(this.createPattern(EXCPTRN[idx])); } } } /** * In the case of log filtering the important * thing is whether the log entry should be * used. Therefore, the method will only * return true if the entry should be used. * Since the interface defines both inclusion * and exclusion, that means by default * inclusion filtering assumes all entries * are excluded unless it matches. In the * case of exlusion filtering, it assumes * all entries are included unless it * matches, which means it should be * excluded. * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#isFiltered(java.lang.String) * @param path * @return boolean */ public boolean isFiltered(String path) { // we do a quick check to see if any // filters are set. If not we just // return false to be efficient. if (this.FILEFILTER || this.PTRNFILTER || this.CHANGEEXT) { if (this.FILEFILTER) { return filterFile(path); } else if (this.PTRNFILTER) { return filterPattern(path); } else if (this.CHANGEEXT) { return replaceExtension(path); } else { return false; } } else { return false; } } /** * Filter the file. The implementation performs * the exclusion first before the inclusion. * This means if a file name is in both string * arrays, the exclusion will take priority. * Depending on how users expect this to work, * we may want to change the priority so that * inclusion is performed first and exclusion * second. Another possible alternative is to * perform both inclusion and exclusion. * Doing so would make the most sense if the * method throws an exception and tells the * user the same filename is in both the * include and exclude array. * @param file * @return boolean */ protected boolean filterFile(String file) { // double check this logic make sure it // makes sense if (this.EXCFILE != null) { return excFile(file); } else if (this.INCFILE != null) { return incFile(file); } return false; } /** * Method implements the logic for filtering * file name inclusion. The method iterates * through the array and uses indexOf. Once * it finds a match, it won't bother with * the rest of the filenames in the array. * @param text * @return boolean include */ public boolean incFile(String text) { // inclusion filter assumes most of // the files are not wanted, therefore // usefile is set to false unless it // matches. this.USEFILE = false; for (int idx = 0; idx < this.INCFILE.length; idx++) { if (text.indexOf(this.INCFILE[idx]) > -1) { this.USEFILE = true; break; } } return this.USEFILE; } /** * Method implements the logic for filtering * file name exclusion. The method iterates * through the array and uses indexOf. Once it * finds a match, it won't bother with the * rest of the filenames in the array. * @param text * @return boolean exclude */ public boolean excFile(String text) { // exclusion filter assumes most of // the files are used, therefore // usefile is set to true, unless // it matches. this.USEFILE = true; boolean exc = false; for (int idx = 0; idx < this.EXCFILE.length; idx++) { if (text.indexOf(this.EXCFILE[idx]) > -1) { exc = true; this.USEFILE = false; break; } } return exc; } /** * The current implemenation assumes * the user has checked the regular * expressions so that they don't cancel * each other. The basic assumption is * the method will return true if the * text should be filtered. If not, it * will return false, which means it * should not be filtered. * @param text * @return boolean */ protected boolean filterPattern(String text) { if (MATCHER == null) { MATCHER = new Perl5Matcher(); } if (this.INCPTRN != null) { return incPattern(text); } else if (this.EXCPTRN != null) { return excPattern(text); } return false; } /** * By default, the method assumes the entry is * not included, unless it matches. In that case, * it will return true. * @param text * @return true if text is included */ protected boolean incPattern(String text) { this.USEFILE = false; for (int idx = 0; idx < this.INCPATTERNS.size(); idx++) { if (MATCHER.contains(text, (Pattern) this.INCPATTERNS.get(idx))) { this.USEFILE = true; break; } } return this.USEFILE; } /** * The method assumes by default the text is * not excluded. If the text matches the * pattern, it will then return true. * @param text * @return true if text is excluded */ protected boolean excPattern(String text) { this.USEFILE = true; boolean exc = false; for (int idx = 0; idx < this.EXCPATTERNS.size(); idx++) { if (MATCHER.contains(text, (Pattern) this.EXCPATTERNS.get(idx))) { exc = true; this.USEFILE = false; break; } } return exc; } /** * Method uses indexOf to replace the old * extension with the new extesion. It * might be good to use regular expression, * but for now this is a simple method. * The method isn't designed to replace * multiple instances of the text, since * that isn't how file extensions work. * If the string contains more than one * instance of the old extension, only * the first instance will be replaced. * @param text * @return boolean */ public boolean replaceExtension(String text) { int pt = text.indexOf(this.OLDEXT); if (pt > -1) { int extsize = this.OLDEXT.length(); this.NEWFILE = text.substring(0, pt) + this.NEWEXT + text.substring(pt + extsize); return true; } else { return false; } } /** * The current implementation checks the boolean * if the text should be used or not. isFilter( * string) has to be called first. * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#filter(java.lang.String) */ public String filter(String text) { if (this.CHANGEEXT) { return this.NEWFILE; } else if (this.USEFILE) { return text; } else { return null; } } /** * create a new pattern object from * the string. * @param pattern * @return Pattern */ public Pattern createPattern(String pattern) { try { Perl5Compiler comp = new Perl5Compiler(); return comp.compile(pattern, Perl5Compiler.READ_ONLY_MASK); } catch (Exception exception) { exception.printStackTrace(); return null; } } /////////////////////// Start of Test Code ////////////////////// public static class Test extends JMeterTestCase { private static final String TESTSTR = "/test/helloworld.html"; private static final String TESTSTROUT = "/test/helloworld.jsp"; private static class TestData{ private final String file; private final boolean exclfile; private final boolean inclfile; private final boolean exclpatt; private final boolean inclpatt; TestData(String f, boolean exf, boolean inf, boolean exp, boolean inp){ file = f; exclfile = exf; inclfile = inf; exclpatt = exp; inclpatt = inp; } } private static final String[] INCL = { "hello.html", "index.html", "/index.jsp" }; private static final String[] PATTERNS = { "index", ".jtml" }; private static final TestData[] TESTDATA = { // file exclf inclf exclp inclp new TestData("/test/hello.jsp", true, false, true, false), new TestData("/test/one/hello.html", false, true, true, false), new TestData("hello.jsp", true, false, true, false), new TestData("hello.htm", true, false, true, false), new TestData("/test/open.jsp", true, false, true, false), new TestData("/test/open.html", true, false, true, false), new TestData("/index.jsp", false, true, false, true), new TestData("/index.jhtml", true, false, false, true), new TestData("newindex.jsp", true, false, false, true), new TestData("oldindex.jsp", true, false, false, true), new TestData("oldindex1.jsp", true, false, false, true), new TestData("oldindex2.jsp", true, false, false, true), new TestData("oldindex3.jsp", true, false, false, true), new TestData("oldindex4.jsp", true, false, false, true), new TestData("oldindex5.jsp", true, false, false, true), new TestData("oldindex6.jsp", true, false, false, true), new TestData("/test/index.htm", true, false, false, true) }; public void testConstruct() { new LogFilter(); } private LogFilter testf; public void setUp() { testf = new LogFilter(); } public void testReplaceExtension() { testf.setReplaceExtension("html", "jsp"); testf.isFiltered(TESTSTR);// set the required variables assertEquals(TESTSTROUT,testf.filter(TESTSTR)); } public void testExcludeFiles() { testf.excludeFiles(INCL); for (int idx = 0; idx < TESTDATA.length; idx++) { TestData td = TESTDATA[idx]; String theFile = td.file; boolean expect = td.exclfile; testf.isFiltered(theFile); String line = testf.filter(theFile); if (line != null) { assertTrue("Expect to accept "+theFile,expect); } else { assertFalse("Expect to reject "+theFile,expect); } } } public void testIncludeFiles() { testf.includeFiles(INCL); for (int idx = 0; idx < TESTDATA.length; idx++) { TestData td = TESTDATA[idx]; String theFile = td.file; boolean expect = td.inclfile; testf.isFiltered(theFile); String line = testf.filter(theFile); if (line != null) { assertTrue("Expect to accept "+theFile,expect); } else { assertFalse("Expect to reject "+theFile,expect); } } } public void testExcludePattern() { testf.excludePattern(PATTERNS); for (int idx = 0; idx < TESTDATA.length; idx++) { TestData td = TESTDATA[idx]; String theFile = td.file; boolean expect = td.exclpatt; testf.isFiltered(theFile); String line = testf.filter(theFile); if (line != null) { assertTrue("Expect to accept "+theFile,expect); } else { assertFalse("Expect to reject "+theFile,expect); } } } public void testIncludePattern() { testf.includePattern(PATTERNS); for (int idx = 0; idx < TESTDATA.length; idx++) { TestData td = TESTDATA[idx]; String theFile = td.file; boolean expect = td.inclpatt; testf.isFiltered(theFile); String line = testf.filter(theFile); if (line != null) { assertTrue("Expect to accept "+theFile,expect); } else { assertFalse("Expect to reject "+theFile,expect); } } } } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.