lucenequerybuilder.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 986 行 · 第 1/3 页

JAVA
986
字号
            }            QueryParser parser = new QueryParser(fieldname, analyzer);            parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND);            // replace escaped ' with just '            StringBuffer query = new StringBuffer();            String textsearch = node.getQuery();            // the default lucene query parser recognizes 'AND' and 'NOT' as            // keywords.            textsearch = textsearch.replaceAll("AND", "and");            textsearch = textsearch.replaceAll("NOT", "not");            boolean escaped = false;            for (int i = 0; i < textsearch.length(); i++) {                if (textsearch.charAt(i) == '\\') {                    if (escaped) {                        query.append("\\\\");                        escaped = false;                    } else {                        escaped = true;                    }                } else if (textsearch.charAt(i) == '\'') {                    if (escaped) {                        escaped = false;                    }                    query.append(textsearch.charAt(i));                } else {                    if (escaped) {                        query.append('\\');                        escaped = false;                    }                    query.append(textsearch.charAt(i));                }            }            Query context = parser.parse(query.toString());            if (relPath != null && (!node.getReferencesProperty() || relPath.getLength() > 1)) {                // text search on some child axis                Path.PathElement[] elements = relPath.getElements();                for (int i = elements.length - 1; i >= 0; i--) {                    String name = null;                    if (!elements[i].getName().equals(RelationQueryNode.STAR_NAME_TEST)) {                        name = NameFormat.format(elements[i].getName(), nsMappings);;                    }                    // join text search with name test                    // if path references property that's elements.length - 2                    // if path references node that's elements.length - 1                    if (name != null                            && ((node.getReferencesProperty() && i == elements.length - 2)                                || (!node.getReferencesProperty() && i == elements.length - 1))) {                        Query q = new TermQuery(new Term(FieldNames.LABEL, name));                        BooleanQuery and = new BooleanQuery();                        and.add(q, Occur.MUST);                        and.add(context, Occur.MUST);                        context = and;                    } else if ((node.getReferencesProperty() && i < elements.length - 2)                            || (!node.getReferencesProperty() && i < elements.length - 1)) {                        // otherwise do a parent axis step                        context = new ParentAxisQuery(context, name);                    }                }                // finally select parent                context = new ParentAxisQuery(context, null);            }            return context;        } catch (NamespaceException e) {            exceptions.add(e);        } catch (ParseException e) {            exceptions.add(e);        } catch (NoPrefixDeclaredException e) {            exceptions.add(e);        }        return null;    }    public Object visit(PathQueryNode node, Object data) {        Query context = null;        LocationStepQueryNode[] steps = node.getPathSteps();        if (steps.length > 0) {            if (node.isAbsolute() && !steps[0].getIncludeDescendants()) {                // eat up first step                QName nameTest = steps[0].getNameTest();                if (nameTest == null) {                    // this is equivalent to the root node                    context = new TermQuery(new Term(FieldNames.PARENT, ""));                } else if (nameTest.getLocalName().length() == 0) {                    // root node                    context = new TermQuery(new Term(FieldNames.PARENT, ""));                } else {                    // then this is a node != the root node                    // will never match anything!                    String name = "";                    try {                        name = NameFormat.format(nameTest, nsMappings);                    } catch (NoPrefixDeclaredException e) {                        exceptions.add(e);                    }                    BooleanQuery and = new BooleanQuery();                    and.add(new TermQuery(new Term(FieldNames.PARENT, "")), Occur.MUST);                    and.add(new TermQuery(new Term(FieldNames.LABEL, name)), Occur.MUST);                    context = and;                }                LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1];                System.arraycopy(steps, 1, tmp, 0, steps.length - 1);                steps = tmp;            } else {                // path is 1) relative or 2) descendant-or-self                // use root node as context                context = new TermQuery(new Term(FieldNames.PARENT, ""));            }        } else {            exceptions.add(new InvalidQueryException("Number of location steps must be > 0"));        }        // loop over steps        for (int i = 0; i < steps.length; i++) {            context = (Query) steps[i].accept(this, context);        }        if (data instanceof BooleanQuery) {            BooleanQuery constraint = (BooleanQuery) data;            if (constraint.getClauses().length > 0) {                constraint.add(context, Occur.MUST);                context = constraint;            }        }        return context;    }    public Object visit(LocationStepQueryNode node, Object data) {        Query context = (Query) data;        BooleanQuery andQuery = new BooleanQuery();        if (context == null) {            exceptions.add(new IllegalArgumentException("Unsupported query"));        }        // predicate on step?        Object[] predicates = node.acceptOperands(this, data);        for (int i = 0; i < predicates.length; i++) {            andQuery.add((Query) predicates[i], Occur.MUST);        }        // check for position predicate        QueryNode[] pred = node.getPredicates();        for (int i = 0; i < pred.length; i++) {            if (pred[i].getType() == QueryNode.TYPE_RELATION) {                RelationQueryNode pos = (RelationQueryNode) pred[i];                if (pos.getValueType() == QueryConstants.TYPE_POSITION) {                    node.setIndex(pos.getPositionValue());                }            }        }        TermQuery nameTest = null;        if (node.getNameTest() != null) {            try {                String internalName = NameFormat.format(node.getNameTest(), nsMappings);                nameTest = new TermQuery(new Term(FieldNames.LABEL, internalName));            } catch (NoPrefixDeclaredException e) {                // should never happen                exceptions.add(e);            }        }        if (node.getIncludeDescendants()) {            if (nameTest != null) {                andQuery.add(new DescendantSelfAxisQuery(context, nameTest), Occur.MUST);            } else {                // descendant-or-self with nametest=*                if (predicates.length > 0) {                    // if we have a predicate attached, the condition acts as                    // the sub query.                    // only use descendant axis if path is not //*                    // otherwise the query for the predicate can be used itself                    PathQueryNode pathNode = (PathQueryNode) node.getParent();                    if (pathNode.getPathSteps()[0] != node) {                        Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false);                        andQuery = new BooleanQuery();                        andQuery.add(subQuery, Occur.MUST);                    }                } else {                    // todo this will traverse the whole index, optimize!                    Query subQuery = null;                    try {                        subQuery = new MatchAllQuery(NameFormat.format(QName.JCR_PRIMARYTYPE, nsMappings));                    } catch (NoPrefixDeclaredException e) {                        // will never happen, prefixes are created when unknown                    }                    // only use descendant axis if path is not //*                    PathQueryNode pathNode = (PathQueryNode) node.getParent();                    if (pathNode.getPathSteps()[0] != node) {                        context = new DescendantSelfAxisQuery(context, subQuery);                        andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST);                    } else {                        andQuery.add(subQuery, Occur.MUST);                    }                }            }        } else {            // name test            if (nameTest != null) {                andQuery.add(new ChildAxisQuery(sharedItemMgr, context, nameTest.getTerm().text(), node.getIndex()), Occur.MUST);            } else {                // select child nodes                andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST);            }        }        return andQuery;    }    public Object visit(DerefQueryNode node, Object data) {        Query context = (Query) data;        if (context == null) {            exceptions.add(new IllegalArgumentException("Unsupported query"));        }        try {            String refProperty = NameFormat.format(node.getRefProperty(), nsMappings);            String nameTest = null;            if (node.getNameTest() != null) {                nameTest = NameFormat.format(node.getNameTest(), nsMappings);            }            if (node.getIncludeDescendants()) {                Query refPropQuery = new MatchAllQuery(refProperty);                context = new DescendantSelfAxisQuery(context, refPropQuery, false);            }            context = new DerefQuery(context, refProperty, nameTest);            // attach predicates            Object[] predicates = node.acceptOperands(this, data);            if (predicates.length > 0) {                BooleanQuery andQuery = new BooleanQuery();                for (int i = 0; i < predicates.length; i++) {                    andQuery.add((Query) predicates[i], Occur.MUST);                }                andQuery.add(context, Occur.MUST);                context = andQuery;            }        } catch (NoPrefixDeclaredException e) {            // should never happen            exceptions.add(e);        }        return context;    }    public Object visit(RelationQueryNode node, Object data) {        Query query;        String[] stringValues = new String[1];        switch (node.getValueType()) {            case 0:                // not set: either IS NULL or IS NOT NULL                break;            case QueryConstants.TYPE_DATE:                stringValues[0] = DateField.dateToString(node.getDateValue());                break;            case QueryConstants.TYPE_DOUBLE:                stringValues[0] = DoubleField.doubleToString(node.getDoubleValue());                break;            case QueryConstants.TYPE_LONG:                stringValues[0] = LongField.longToString(node.getLongValue());                break;            case QueryConstants.TYPE_STRING:                if (node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL                        || node.getOperation() == QueryConstants.OPERATION_EQ_VALUE                        || node.getOperation() == QueryConstants.OPERATION_NE_GENERAL                        || node.getOperation() == QueryConstants.OPERATION_NE_VALUE) {                    // only use coercing on non-range operations                    QName propertyName = node.getRelativePath().getNameElement().getName();                    stringValues = getStringValues(propertyName, node.getStringValue());                } else {                    stringValues[0] = node.getStringValue();                }                break;            case QueryConstants.TYPE_POSITION:                // ignore position. is handled in the location step                return null;            default:                throw new IllegalArgumentException("Unknown relation type: "                        + node.getValueType());        }        if (node.getRelativePath() == null) {            exceptions.add(new InvalidQueryException("@* not supported in predicate"));            return data;        }        // get property transformation        final int[] transform = new int[]{TransformConstants.TRANSFORM_NONE};        node.acceptOperands(new DefaultQueryNodeVisitor() {            public Object visit(PropertyFunctionQueryNode node, Object data) {                if (node.getFunctionName().equals(PropertyFunctionQueryNode.LOWER_CASE)) {                    transform[0] = TransformConstants.TRANSFORM_LOWER_CASE;                } else if (node.getFunctionName().equals(PropertyFunctionQueryNode.UPPER_CASE)) {                    transform[0] = TransformConstants.TRANSFORM_UPPER_CASE;                }                return data;            }        }, null);        Path relPath = node.getRelativePath();        String field = "";        try {            field = NameFormat.format(relPath.getNameElement().getName(), nsMappings);        } catch (NoPrefixDeclaredException e) {            // should never happen            exceptions.add(e);        }        switch (node.getOperation()) {            case QueryConstants.OPERATION_EQ_VALUE:      // =            case QueryConstants.OPERATION_EQ_GENERAL:                BooleanQuery or = new BooleanQuery();                for (int i = 0; i < stringValues.length; i++) {                    Term t = new Term(FieldNames.PROPERTIES,                                FieldNames.createNamedValue(field, stringValues[i]));                    Query q;                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {                        q = new CaseTermQuery.Upper(t);                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {                        q = new CaseTermQuery.Lower(t);                    } else {                        q = new TermQuery(t);                    }                    or.add(q, Occur.SHOULD);                }                query = or;                if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?