1 package org.apache.lucene.search.regex;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import org.apache.regexp.RE;
21 import org.apache.regexp.REProgram;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Method;
26 * Implementation tying <a href="http://jakarta.apache.org/regexp">Jakarta
27 * Regexp</a> to RegexQuery. Jakarta Regepx internally supports a
28 * {@link #prefix} implementation which can offer performance gains under
29 * certain circumstances. Yet, the implementation appears to be rather shaky as
30 * it doesn't always provide a prefix even if one would exist.
32 public class JakartaRegexpCapabilities implements RegexCapabilities {
35 private static Field prefixField;
36 private static Method getPrefixMethod;
39 getPrefixMethod = REProgram.class.getMethod("getPrefix");
40 } catch (Exception e) {
41 getPrefixMethod = null;
44 prefixField = REProgram.class.getDeclaredField("prefix");
45 prefixField.setAccessible(true);
46 } catch (Exception e) {
51 // Define the flags that are possible. Redefine them here
52 // to avoid exposing the RE class to the caller.
54 private int flags = RE.MATCH_NORMAL;
57 * Flag to specify normal, case-sensitive matching behaviour. This is the default.
59 public static final int FLAG_MATCH_NORMAL = RE.MATCH_NORMAL;
62 * Flag to specify that matching should be case-independent (folded)
64 public static final int FLAG_MATCH_CASEINDEPENDENT = RE.MATCH_CASEINDEPENDENT;
67 * Constructs a RegexCapabilities with the default MATCH_NORMAL match style.
69 public JakartaRegexpCapabilities() {}
72 * Constructs a RegexCapabilities with the provided match flags.
73 * Multiple flags should be ORed together.
75 * @param flags The matching style
77 public JakartaRegexpCapabilities(int flags)
82 public void compile(String pattern) {
83 regexp = new RE(pattern, this.flags);
86 public boolean match(String string) {
87 return regexp.match(string);
90 public String prefix() {
93 if (getPrefixMethod != null) {
94 prefix = (char[]) getPrefixMethod.invoke(regexp.getProgram());
95 } else if (prefixField != null) {
96 prefix = (char[]) prefixField.get(regexp.getProgram());
100 return prefix == null ? null : new String(prefix);
101 } catch (Exception e) {
102 // if we cannot get the prefix, return none
108 public boolean equals(Object o) {
109 if (this == o) return true;
110 if (o == null || getClass() != o.getClass()) return false;
112 final JakartaRegexpCapabilities that = (JakartaRegexpCapabilities) o;
114 if (regexp != null ? !regexp.equals(that.regexp) : that.regexp != null) return false;
120 public int hashCode() {
121 return (regexp != null ? regexp.hashCode() : 0);