/*
* Copyright (C) 2001 Mika Riekkinen, Joni Suominen
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package alt.jiapi.instrumentor;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Category;
import alt.jiapi.Instrumentor;
import alt.jiapi.Runtime;
import alt.jiapi.Rule;
import alt.jiapi.reflect.InstructionList;
/**
* GrepInstrumentor finds known spots from intstruction lists and forwards
* them to next Instrumentor in chain. Known spots are found by Strategies
* given to this class. This instrumentor can be configured to work in
* reverse mode, where known spots are blocked from further instrumentation.<p>
*
* If the instructionList, that is being instrumented is as follows:
*
* <blockquote>
* <code>iiiiiiiXXXXXXXiiiiiiiXXXXXXX</code>
* </blockquote>
*
* where <code>i</code> represents an Instruction, that is not of interest.
* <code>X</code> represents an interesting Instruction, which is
* found by Strategy given to this Instrumentor. InstructionList
* is then split into two InstructionLists as follows:
* <blockquote>
* <code>XXXXXXX XXXXXXX</code>
* </blockquote>
* However, if GrepInstrumentor was configred in reverse mode, it would
* split InstructionList as follows:
* <blockquote>
* <code>iiiiiii iiiiiii</code>
* </blockquote>
* each of which are forwarded to the following Instrumentor in chain.
*
* @see Strategy
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.11 $ $Date: 2004/03/15 14:47:53 $
*/
public class GrepInstrumentor extends AbstractInstrumentor {
private static Category log = Runtime.getLogCategory(GrepInstrumentor.class);
private Strategy strategy;
/**
* This constructor creates GrepInstrumentor that operates in
* normal mode. That is, known spots found by Strategies are forwarded
* to next Instrumentor in chain. Unknown spots are blocked from
* further instrumentation.
*
* @param strategy A Strategy to be used in finding known spots
* from InstructionLists
*/
public GrepInstrumentor(Strategy strategy) {
log.info("GrepInstrumentor: " + strategy);
this.strategy = strategy;
}
/**
* Splits given InstructionList into set of InstructionLists.
*/
public void instrument(InstructionList il) {
log.info("Instrumenting " + getCurrentClass().getName() + "." +
il.getDeclaringMethod().getName());
((AbstractStrategy)strategy).setInstrumentation(getInstrumentation());
//List boundaries = strategy.findBoundaries(il);
List hotSpots = strategy.findHotSpots(il);
Iterator iter = hotSpots.iterator();
while (iter.hasNext()) {
HotSpot hs = (HotSpot)iter.next();
InstructionList view = il.createView(hs.getStart(), hs.getEnd());
// System.out.println("Grep:" + hs.getStart() + "-" + hs.getEnd() +
// ":" + view);
forward(view);
}
}
/**
* Set the resolution, that is to be used by this GrepInstrumentor
* and its Strategy.
*
* @param resolution Resolution to be used.
*/
public void setResolution(String resolution) {
setResolutions(new String[] {resolution});
}
/**
* Set the resolutions, that are to be used by this GrepInstrumentor
* and its Strategy.
*
* @param resolutions Resolutions to be used.
*/
public void setResolutions(String[] resolutions) {
if (strategy instanceof AbstractStrategy) {
((AbstractStrategy)strategy).setResolutions(resolutions);
}
else {
// Should we declare matcher method in Strategy.
// Or should we get rid of Strategy and use AbstractStrategy
// in APIs
log.warn("Cannot set resolutions to " + strategy +
": It is not an instanceof AbstractStrategy");
}
}
/**
* Converts this GrepInstrumentor to String.
*/
public String toString() {
return super.toString() + "#" + strategy.toString();
}
}