001package net.sf.logdistiller; 002 003/* 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017import java.io.*; 018import java.util.Collections; 019import java.util.HashMap; 020import java.util.Map; 021import java.util.regex.Pattern; 022 023import org.jdom.Element; 024 025/** 026 * Match of an attribute of a LogEvent. Match type can be either <code>contains</code>, <code>equals</code>, 027 * <code>startsWith</code>, <code>endsWith</code> or <code>regexp</code>, and can be negated by preceding type with 028 * <code>!</code>. 029 */ 030public class Match 031 implements Serializable 032{ 033 private static final long serialVersionUID = -1809458932445222708L; 034 035 private final String attribute; 036 037 private final boolean not; 038 039 private final Function function; 040 041 private transient LogType.AttributeInfo attributeInfo; 042 043 public Match( String attribute, String type, String reference ) 044 { 045 this.attribute = attribute; 046 this.not = type.startsWith( "!" ); 047 if ( not ) 048 { 049 type = type.substring( 1 ); 050 } 051 this.function = Match.Function.getInstance( type, reference ); 052 } 053 054 public boolean match( LogEvent le ) 055 { 056 // initialize attributeInfo if necessary 057 if ( attributeInfo == null ) 058 { 059 LogType.Description description = le.getFactory().getDescription(); 060 attributeInfo = description.getAttributeInfo( attribute ); 061 } 062 063 String value = le.getValue( attributeInfo ); 064 boolean result = function.checkValue( value ); 065 return ( not ? !result : result ); 066 } 067 068 public Element dump() 069 { 070 Element elmt = new Element( "match" ); 071 elmt.setAttribute( "attribute", attribute ); 072 elmt.setAttribute( "type", ( not ? "!" : "" ) + function.getId() ); 073 elmt.setText( function.reference ); 074 return elmt; 075 } 076 077 private static abstract class Function 078 implements Serializable 079 { 080 private static final long serialVersionUID = 1072441995042764838L; 081 082 public final static Map<String, Class<? extends Function>> FUNCTIONS; 083 static 084 { 085 Map<String, Class<? extends Function>> map = new HashMap<String, Class<? extends Function>>(); 086 map.put( Contains.ID, Contains.class ); 087 map.put( Equals.ID, Equals.class ); 088 map.put( StartsWith.ID, StartsWith.class ); 089 map.put( EndsWith.ID, EndsWith.class ); 090 map.put( Regexp.ID, Regexp.class ); 091 FUNCTIONS = Collections.unmodifiableMap( map ); 092 } 093 094 public static Function getInstance( String type, String reference ) 095 { 096 Class<? extends Function> functionClass = FUNCTIONS.get( type ); 097 if ( functionClass == null ) 098 { 099 throw new IllegalArgumentException( "function type not supported '" + type + "'" ); 100 } 101 try 102 { 103 Function function = functionClass.newInstance(); 104 function.setReference( reference ); 105 return function; 106 } 107 catch ( IllegalAccessException iae ) 108 { 109 // can't happen 110 throw new RuntimeException( "an impossible condition has arrived...", iae ); 111 } 112 catch ( InstantiationException ie ) 113 { 114 // can't happen 115 throw new RuntimeException( "an impossible condition has arrived...", ie ); 116 } 117 } 118 119 protected String reference; 120 121 public void setReference( String reference ) 122 { 123 this.reference = reference; 124 } 125 126 public abstract String getId(); 127 128 /** 129 * check if the given value matches the reference. 130 * 131 * @param value String the value to compare to reference 132 * @return boolean 133 */ 134 public abstract boolean checkValue( String value ); 135 } 136 137 protected static class Contains 138 extends Function 139 { 140 private static final long serialVersionUID = 4613611844726287358L; 141 142 public static final String ID = "contains"; 143 144 public String getId() 145 { 146 return ID; 147 } 148 149 public boolean checkValue( String value ) 150 { 151 return ( value.indexOf( reference ) >= 0 ); 152 } 153 } 154 155 protected static class Equals 156 extends Function 157 { 158 private static final long serialVersionUID = -6539918940865536415L; 159 160 public static final String ID = "equals"; 161 162 public String getId() 163 { 164 return ID; 165 } 166 167 public boolean checkValue( String value ) 168 { 169 return reference.equals( value ); 170 } 171 } 172 173 protected static class StartsWith 174 extends Function 175 { 176 private static final long serialVersionUID = 5014914695776363132L; 177 178 public static final String ID = "startsWith"; 179 180 public String getId() 181 { 182 return ID; 183 } 184 185 public boolean checkValue( String value ) 186 { 187 return value.startsWith( reference ); 188 } 189 } 190 191 protected static class EndsWith 192 extends Function 193 { 194 private static final long serialVersionUID = 1819477635452601804L; 195 196 public static final String ID = "endsWith"; 197 198 public String getId() 199 { 200 return ID; 201 } 202 203 public boolean checkValue( String value ) 204 { 205 return value.endsWith( reference ); 206 } 207 } 208 209 protected static class Regexp 210 extends Function 211 { 212 private static final long serialVersionUID = -2067188055591690252L; 213 214 public static final String ID = "regexp"; 215 216 public String getId() 217 { 218 return ID; 219 } 220 221 private transient Pattern pattern; 222 223 public void setReference( String reference ) 224 { 225 super.setReference( reference ); 226 updatePattern(); 227 } 228 229 private void updatePattern() 230 { 231 pattern = Pattern.compile( reference ); 232 } 233 234 private void readObject( ObjectInputStream in ) 235 throws IOException, ClassNotFoundException 236 { 237 in.defaultReadObject(); 238 updatePattern(); 239 } 240 241 public boolean checkValue( String value ) 242 { 243 return pattern.matcher( value ).find(); 244 } 245 } 246}