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

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

    
113
}