View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j.rule;
19  
20  import org.apache.log4j.spi.LoggingEvent;
21  import org.apache.log4j.spi.LoggingEventFieldResolver;
22  
23  import java.io.IOException;
24  import java.util.HashSet;
25  import java.util.Map;
26  import java.util.Set;
27  import java.util.Stack;
28  import java.util.regex.Matcher;
29  import java.util.regex.Pattern;
30  import java.util.regex.PatternSyntaxException;
31  
32  /***
33   * A Rule class supporting java.util.regex regular expression syntax.
34   *
35   * @author Scott Deboy (sdeboy@apache.org)
36   */
37  public class LikeRule extends AbstractRule {
38      /***
39       * Serialization ID.
40       */
41    static final long serialVersionUID = -3375458885595683156L;
42  
43      /***
44       * Resolver.
45       */
46    private static final LoggingEventFieldResolver RESOLVER =
47              LoggingEventFieldResolver.getInstance();
48      /***
49       * Pattern.
50       */
51    private transient Pattern pattern;
52      /***
53       * Regular expression matcher.
54       */
55    private transient Matcher matcher = null;
56      /***
57       * Field.
58       */
59    private transient String field;
60  
61      /***
62       * Create new instance.
63       * @param field field
64       * @param pattern pattern
65       */
66    private LikeRule(final String field, final Pattern pattern) {
67      super();
68      if (!RESOLVER.isField(field)) {
69          throw new IllegalArgumentException(
70                  "Invalid LIKE rule - " + field + " is not a supported field");
71      }
72  
73      this.field = field;
74      this.pattern = pattern;
75    }
76  
77      /***
78       * Create new instance from top two elements of stack.
79       * @param stack stack
80       * @return new instance
81       */
82    public static Rule getRule(final Stack stack) {
83        if (stack.size() < 2) {
84            throw new IllegalArgumentException(
85                    "Invalid LIKE rule - expected two parameters but received "
86                            + stack.size());
87        }
88  
89        String p2 = stack.pop().toString();
90        String p1 = stack.pop().toString();
91        return getRule(p1, p2);
92    }
93  
94      /***
95       * Create new instance.
96       * @param field field
97       * @param pattern pattern
98       * @return new instance
99       */
100   public static Rule getRule(final String field, final String pattern) {
101     try {
102         return new LikeRule(field, Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
103     } catch (PatternSyntaxException e) {
104         throw new IllegalArgumentException(
105                 "Invalid LIKE rule - " + e.getMessage());
106     }
107   }
108 
109     /*** {@inheritDoc} */
110   public boolean evaluate(final LoggingEvent event, Map matches) {
111     //no need to figure out what part of the string matched, just set the entire string as a match
112     Object input = RESOLVER.getValue(field, event);
113     if((input != null) && (pattern != null)) {
114         if (matcher == null) {
115             matcher = pattern.matcher(input.toString());
116         } else {
117             matcher.reset(input.toString());
118         }
119         boolean result = matcher.matches();
120         if (result && matches != null) {
121             Set entries = (Set) matches.get(field.toUpperCase());
122             if (entries == null) {
123                 entries = new HashSet();
124                 matches.put(field.toUpperCase(), entries);
125             }
126             entries.add(input);
127         }
128         return result;
129     }
130     return false;
131   }
132 
133   /***
134     * Deserialize the state of the object.
135     *
136     * @param in object input stream
137     *
138     * @throws IOException if IOException during deserialization
139     * @throws ClassNotFoundException if class not found.
140     */
141    private void readObject(final java.io.ObjectInputStream in)
142      throws IOException, ClassNotFoundException {
143          try {
144            field = (String) in.readObject();
145            String patternString = (String) in.readObject();
146            pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
147          } catch (PatternSyntaxException e) {
148              throw new IOException("Invalid LIKE rule - " + e.getMessage());
149          }
150    }
151 
152    /***
153     * Serialize the state of the object.
154     *
155     * @param out object output stream
156     *
157     * @throws IOException if IOException during serialization
158     */
159    private void writeObject(final java.io.ObjectOutputStream out)
160      throws IOException {
161      out.writeObject(field);
162      out.writeObject(pattern.pattern());
163    }
164 }