001 // This file is part of the program FRYSK. 002 // 003 // Copyright 2005, 2006, 2007, 2008, Red Hat Inc. 004 // 005 // FRYSK is free software; you can redistribute it and/or modify it 006 // under the terms of the GNU General Public License as published by 007 // the Free Software Foundation; version 2 of the License. 008 // 009 // FRYSK is distributed in the hope that it will be useful, but 010 // WITHOUT ANY WARRANTY; without even the implied warranty of 011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 // General Public License for more details. 013 // 014 // You should have received a copy of the GNU General Public License 015 // along with FRYSK; if not, write to the Free Software Foundation, 016 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 017 // 018 // In addition, as a special exception, Red Hat, Inc. gives You the 019 // additional right to link the code of FRYSK with code not covered 020 // under the GNU General Public License ("Non-GPL Code") and to 021 // distribute linked combinations including the two, subject to the 022 // limitations in this paragraph. Non-GPL Code permitted under this 023 // exception must only link to the code of FRYSK through those well 024 // defined interfaces identified in the file named EXCEPTION found in 025 // the source code files (the "Approved Interfaces"). The files of 026 // Non-GPL Code may instantiate templates or use macros or inline 027 // functions from the Approved Interfaces without causing the 028 // resulting work to be covered by the GNU General Public 029 // License. Only Red Hat, Inc. may make changes or additions to the 030 // list of Approved Interfaces. You must obey the GNU General Public 031 // License in all respects for all of the FRYSK code and other code 032 // used in conjunction with FRYSK except the Non-GPL Code covered by 033 // this exception. If you modify this file, you may extend this 034 // exception to your version of the file, but you are not obligated to 035 // do so. If you do not wish to provide this exception without 036 // modification, you must delete this exception statement from your 037 // version and license this file solely under the GPL without 038 // exception. 039 040 package frysk.ftrace; 041 042 import java.util.Collection; 043 import java.util.Iterator; 044 import java.util.Set; 045 import frysk.rsl.Log; 046 047 public abstract class Rule { 048 private static final Log fine = Log.fine(Rule.class); 049 050 final public boolean addition; 051 final public RuleOptions options; 052 053 protected Rule(boolean addition, RuleOptions options) { 054 this.addition = addition; 055 this.options = options; 056 } 057 058 public String toString() { 059 return (this.addition ? "" : "-") + "/" + 060 (this.options.stackTrace ? "s" : ""); 061 } 062 063 public boolean apply(Collection candidates, 064 Set workingSet, Set stackTraceSet) 065 { 066 boolean matched = false; 067 068 if (this.addition) { 069 // For '+' rules iterate over candidates, 070 // and add what matches to workingSet, and 071 // maybe to stackTraceSet. 072 for (Iterator jt = candidates.iterator(); jt.hasNext(); ) { 073 Object candidate = jt.next(); 074 if (this.matches(candidate)) { 075 matched = true; 076 if (workingSet.add(candidate)) 077 fine.log(this, "add", candidate); 078 if (options.stackTrace 079 && stackTraceSet.add(candidate)) 080 fine.log(this, "stack trace on", candidate); 081 } 082 } 083 } 084 else { 085 // For '-' or '-/s' rules iterate over 086 // workingSet or stackTraceSet, and remove 087 // what matches. 088 Set iterateOver = options.stackTrace ? stackTraceSet : workingSet; 089 for (Iterator jt = iterateOver.iterator(); jt.hasNext(); ) { 090 Object candidate = jt.next(); 091 if (this.matches(candidate)) { 092 matched = true; 093 jt.remove(); 094 if (!options.stackTrace) 095 stackTraceSet.remove(candidate); 096 fine.log(this, "remove", candidate); 097 } 098 } 099 } 100 101 return matched; 102 } 103 104 abstract public boolean matches(Object traceable); 105 }