Package org.knopflerfish.service.um.useradmin.impl

Source Code of org.knopflerfish.service.um.useradmin.impl.LDAPQuery

/*
* Copyright (c) 2003, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.knopflerfish.service.um.useradmin.impl;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Vector;

import org.osgi.framework.InvalidSyntaxException;

/**
* LDAP filter functions.
*
* @author Tommy Bohlin
* @author Jan Stein
* @version $Revision: 1.1.1.1 $
*/
public class LDAPQuery {
    private static final char WILDCARD = 65535;

    private static final String WILDCARD_STRING = new String(
            new char[] { WILDCARD });

    private static final String NULL = "Null query";

    private static final String GARBAGE = "Trailing garbage";

    private static final String MALFORMED = "Malformed query";

    private static final String EMPTY = "Empty list";

    private static final String SUBEXPR = "No subexpression";

    private static final String OPERATOR = "Undefined operator";

    // private static final String TRUNCATED="Truncated expression";
    // private static final String EQUALITY ="Only equality supported";

    private static final int EQ = 0;

    private static final int LE = 1;

    private static final int GE = 2;

    private static final int APPROX = 3;

    // private static final Class[] classArg=new Class[] { String.class };
    // private static final Class[] objectArg=new Class[] { Object.class };

    private static Class classBigDecimal;

    private static Constructor consBigDecimal;

    private static Method compBigDecimal;

    static {
        try {
            classBigDecimal = Class.forName("java.math.BigDecimal");
            consBigDecimal = classBigDecimal
                    .getConstructor(new Class[] { String.class });
            compBigDecimal = classBigDecimal.getMethod("compareTo",
                    new Class[] { classBigDecimal });
        } catch (Exception ignore) {
            classBigDecimal = null;
        }
    }

    boolean val;

    String tail;

    Dictionary prop;

    public static void check(String q) throws InvalidSyntaxException {
        query(q, null);
    }

    public static boolean query(String q, Dictionary p)
            throws InvalidSyntaxException {
        LDAPQuery lq = new LDAPQuery(q, p);
        lq.doQuery();
        if (lq.tail.length() > 0)
            lq.error(GARBAGE);
        return lq.val;
    }

    LDAPQuery(String q, Dictionary p) throws InvalidSyntaxException {
        if (q == null || q.length() == 0)
            error(NULL);
        tail = q;
        prop = p;
    }

    void doQuery() throws InvalidSyntaxException {
        if (tail.length() < 3 || !prefix("("))
            error(MALFORMED);

        switch (tail.charAt(0)) {
        case '&':
            doAnd();
            break;
        case '|':
            doOr();
            break;
        case '!':
            doNot();
            break;
        default:
            doSimple();
            break;
        }

        if (!prefix(")"))
            error(MALFORMED);
    }

    private void doAnd() throws InvalidSyntaxException {
        tail = tail.substring(1);
        boolean val1 = true;
        if (!tail.startsWith("("))
            error(EMPTY);
        do {
            doQuery();
            if (!val)
                val1 = false;
        } while (tail.startsWith("("));
        val = val1;
    }

    private void doOr() throws InvalidSyntaxException {
        tail = tail.substring(1);
        boolean val1 = false;
        if (!tail.startsWith("("))
            error(EMPTY);
        do {
            doQuery();
            if (val)
                val1 = true;
        } while (tail.startsWith("("));
        val = val1;
    }

    private void doNot() throws InvalidSyntaxException {
        tail = tail.substring(1);
        if (!tail.startsWith("("))
            error(SUBEXPR);
        doQuery();
        val = !val;
    }

    private void doSimple() throws InvalidSyntaxException {
        int op = 0;
        Object attr = getAttr();

        if (prefix("="))
            op = EQ;
        else if (prefix("<="))
            op = LE;
        else if (prefix(">="))
            op = GE;
        else if (prefix("~="))
            op = APPROX;
        else
            error(OPERATOR);

        val = compare(attr, op, getValue());
    }

    private boolean prefix(String pre) {
        if (!tail.startsWith(pre))
            return false;
        tail = tail.substring(pre.length());
        return true;
    }

    private Object getAttr() {
        int len = tail.length();
        int ix = 0;
        label: for (; ix < len; ix++) {
            switch (tail.charAt(ix)) {
            case '(':
            case ')':
            case '<':
            case '>':
            case '=':
            case '~':
            case '*':
            case '\\':
                break label;
            }
        }
        String attr = tail.substring(0, ix);
        tail = tail.substring(ix);
        return prop != null ? prop.get(attr) : null;
    }

    private String getValue() {
        StringBuffer sb = new StringBuffer();
        int len = tail.length();
        int ix = 0;
        label: for (; ix < len; ix++) {
            char c = tail.charAt(ix);
            switch (c) {
            case '(':
            case ')':
                break label;
            case '*':
                sb.append(WILDCARD);
                break;
            case '\\':
                if (ix == len - 1)
                    break label;
                sb.append(tail.charAt(++ix));
                break;
            default:
                sb.append(c);
                break;
            }
        }
        tail = tail.substring(ix);
        return sb.toString();
    }

    private void error(String m) throws InvalidSyntaxException {
        throw new InvalidSyntaxException(m, tail);
    }

    private boolean compare(Object obj, int op, String s) {
        if (obj == null)
            return false;
        if (op == EQ && s.equals(WILDCARD_STRING))
            return true;
        try {
            if (obj instanceof String) {
                return compareString((String) obj, op, s);
            } else if (obj instanceof Character) {
                return compareString(obj.toString(), op, s);
            } else if (obj instanceof Boolean) {
                if (op == LE || op == GE)
                    return false;
                return ((Boolean) obj).equals(new Boolean(s));
            } else if (obj instanceof Number) {
                if (obj instanceof Byte) {
                    switch (op) {
                    case LE:
                        return ((Byte) obj).byteValue() <= Byte.parseByte(s);
                    case GE:
                        return ((Byte) obj).byteValue() >= Byte.parseByte(s);
                    default: /* APPROX and EQ */
                        return (new Byte(s)).equals(obj);
                    }
                } else if (obj instanceof Integer) {
                    switch (op) {
                    case LE:
                        return ((Integer) obj).intValue() <= Integer
                                .parseInt(s);
                    case GE:
                        return ((Integer) obj).intValue() >= Integer
                                .parseInt(s);
                    default: /* APPROX and EQ */
                        return (new Integer(s)).equals(obj);
                    }
                } else if (obj instanceof Short) {
                    switch (op) {
                    case LE:
                        return ((Short) obj).shortValue() <= Short
                                .parseShort(s);
                    case GE:
                        return ((Short) obj).shortValue() >= Short
                                .parseShort(s);
                    default: /* APPROX and EQ */
                        return (new Short(s)).equals(obj);
                    }
                } else if (obj instanceof Long) {
                    switch (op) {
                    case LE:
                        return ((Long) obj).longValue() <= Long.parseLong(s);
                    case GE:
                        return ((Long) obj).longValue() >= Long.parseLong(s);
                    default: /* APPROX and EQ */
                        return (new Long(s)).equals(obj);
                    }
                } else if (obj instanceof Float) {
                    switch (op) {
                    case LE:
                        return ((Float) obj).floatValue() <= (new Float(s))
                                .floatValue();
                    case GE:
                        return ((Float) obj).floatValue() >= (new Float(s))
                                .floatValue();
                    default: /* APPROX and EQ */
                        return (new Float(s)).equals(obj);
                    }
                } else if (obj instanceof Double) {
                    switch (op) {
                    case LE:
                        return ((Double) obj).doubleValue() <= (new Double(s))
                                .doubleValue();
                    case GE:
                        return ((Double) obj).doubleValue() >= (new Double(s))
                                .doubleValue();
                    default: /* APPROX and EQ */
                        return (new Double(s)).equals(obj);
                    }
                } else if (obj instanceof BigInteger) {
                    int c = ((BigInteger) obj).compareTo(new BigInteger(s));
                    switch (op) {
                    case LE:
                        return c <= 0;
                    case GE:
                        return c >= 0;
                    default: /* APPROX and EQ */
                        return c == 0;
                    }
                } else if (classBigDecimal != null
                        && classBigDecimal.isInstance(obj)) {
                    Object n = consBigDecimal.newInstance(new Object[] { s });
                    int c = ((Integer) compBigDecimal.invoke(obj,
                            new Object[] { n })).intValue();
                    switch (op) {
                    case LE:
                        return c <= 0;
                    case GE:
                        return c >= 0;
                    default: /* APPROX and EQ */
                        return c == 0;
                    }
                }
            } else if (obj instanceof Vector) {
                for (Enumeration e = ((Vector) obj).elements(); e
                        .hasMoreElements();)
                    if (compare(e.nextElement(), op, s))
                        return true;
            } else if (obj.getClass().isArray()) {
                int len = Array.getLength(obj);
                for (int i = 0; i < len; i++)
                    if (compare(Array.get(obj, i), op, s))
                        return true;
            }
        } catch (Exception e) {
        }
        return false;
    }

    static boolean compareString(String s1, int op, String s2) {
        switch (op) {
        case LE:
            return s1.compareTo(s2) <= 0;
        case GE:
            return s1.compareTo(s2) >= 0;
        case EQ:
            return patSubstr(s1, s2);
        case APPROX:
            return fixupString(s2).equals(fixupString(s1));
        default:
            return false;
        }
    }

    static String fixupString(String s) {
        StringBuffer sb = new StringBuffer();
        int len = s.length();
        boolean isStart = true;
        boolean isWhite = false;
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (Character.isWhitespace(c)) {
                isWhite = true;
            } else {
                if (!isStart && isWhite)
                    sb.append(' ');
                if (Character.isUpperCase(c))
                    c = Character.toLowerCase(c);
                sb.append(c);
                isStart = false;
                isWhite = false;
            }
        }
        return sb.toString();
    }

    static boolean patSubstr(String s, String pat) {
        if (s == null)
            return false;
        if (pat.length() == 0)
            return s.length() == 0;
        if (pat.charAt(0) == WILDCARD) {
            pat = pat.substring(1);
            for (;;) {
                if (patSubstr(s, pat))
                    return true;
                if (s.length() == 0)
                    return false;
                s = s.substring(1);
            }
        }
        if (s.length() == 0 || s.charAt(0) != pat.charAt(0)) {
            return false;
        }
        return patSubstr(s.substring(1), pat.substring(1));
    }
}
TOP

Related Classes of org.knopflerfish.service.um.useradmin.impl.LDAPQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.