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 @ 44009

History | View | Annotate | Download (3.21 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 org.gvsig.expressionevaluator.Function;
9
import org.gvsig.expressionevaluator.Interpreter;
10
import org.gvsig.expressionevaluator.impl.function.operator.AbstractBinaryOperator;
11

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

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

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

    
24

    
25
    public LikeOperator() {
26
        super(Function.GROUP_STRING, "LIKE");
27
    }
28

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

    
118
}