Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.impl / src / main / java / org / gvsig / expressionevaluator / impl / function / predicate / LikeOperator.java @ 44207

History | View | Annotate | Download (3.3 KB)

1
package org.gvsig.expressionevaluator.impl.function.predicate;
2

    
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.Map;
6
import java.util.regex.Matcher;
7
import java.util.regex.Pattern;
8
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
9
import org.gvsig.expressionevaluator.Function;
10
import org.gvsig.expressionevaluator.Interpreter;
11
import org.gvsig.expressionevaluator.impl.function.operator.AbstractBinaryOperator;
12

    
13
/*
14
 * Based on portions of code from org.medfoster.sqljep.function.Like of the
15
 * SQLJEP project ((c) Copyright 2006, Alexey Gaidukov)
16
 * http://sqljep.sourceforge.net/
17
 */
18

    
19
public class LikeOperator extends AbstractBinaryOperator {
20
        protected static final Integer ZERO_OR_MORE_CHARS = 0; 
21
        protected static final Integer ONE_CHAR = 1; 
22

    
23
        protected static Map<String,Pattern> patterns = new HashMap<>();
24

    
25

    
26
    public LikeOperator() {
27
        super(Function.GROUP_STRING, OPERATOR_LIKE, true);
28
    }
29

    
30
    @Override
31
    public boolean allowConstantFolding() {
32
        return true;
33
    }
34
    
35
    @Override
36
    public Object call(Interpreter interpreter, Object op1, Object op2) {       
37
        if( op1 instanceof CharSequence && op2 instanceof CharSequence ) {
38
            boolean value = like(((CharSequence) op1).toString(), ((CharSequence) op2).toString());
39
            return value;
40
        }
41
        throw new IllegalArgumentException("Types not allowed in '"+name()+"' operand.");
42
    }
43
    
44
    public static boolean like(String source, String match) {
45
                Pattern pattern = patterns.get(match);
46
                if (pattern == null) {
47
            if( patterns.size()>20 ) {
48
                patterns = new HashMap<>();
49
            }
50
                        ArrayList<Object> p = compile(match);
51
                        String regexp = toRegExp(p);
52
                        pattern = Pattern.compile(regexp);
53
                        patterns.put(match, pattern);
54
                }
55
                Matcher m = pattern.matcher(source);
56
                return m.find();
57
        }
58
        
59
        protected static ArrayList<Object> compile(String pattern) {
60
                ArrayList<Object> format = new ArrayList<>();
61
                StringBuilder fill = new StringBuilder();
62
                final int plen = pattern.length();
63
                Character lastSymbol = null;
64
                if (pattern.length() > 2 && pattern.charAt(0) == '/' && pattern.charAt(pattern.length()-1) == '/') {
65
                        format.add(pattern.substring(1, pattern.length()-2));
66
                } else {
67
                        for (int i = 0; i < plen; i++) {
68
                                boolean f = false;
69
                                char c = pattern.charAt(i);
70
                                if (lastSymbol != null && lastSymbol == '\\') {
71
                                        lastSymbol = null;
72
                                        fill.append(c);
73
                                } else {
74
                                        if (c == '%') {
75
                                                if (fill.length() > 0) {
76
                                                        format.add(fill.toString());
77
                                                        fill.setLength(0);
78
                                                }
79
                                                format.add(ZERO_OR_MORE_CHARS); 
80
                                        }
81
                                        else if (c == '_') {
82
                                                if (fill.length() > 0) {
83
                                                        format.add(fill.toString());
84
                                                        fill.setLength(0);
85
                                                }
86
                                                format.add(ONE_CHAR); 
87
                                        } else {
88
                                                fill.append(c);
89
                                        }
90
                                        lastSymbol = c;
91
                                }
92
                        }
93
                        if (fill.length() > 0) {
94
                                format.add(fill.toString());
95
                        }
96
                }
97
                return format;
98
        }
99
        
100
        public static String toRegExp(ArrayList<Object> pattern) {
101
                if (pattern != null) {
102
                        StringBuilder str = new StringBuilder("^");
103
                        for (Object o : pattern) {
104
                                if (o == ZERO_OR_MORE_CHARS) {
105
                                        str.append(".*?");
106
                                }
107
                                else if (o == ONE_CHAR) {
108
                                        str.append(".?");
109
                                } else {
110
                                        str.append((String)o);
111
                                }
112
                        }
113
                        return str.toString();
114
                } else {
115
                        return null;
116
                }
117
        }    
118

    
119
}