com.ebay.cloud.cms.dal.search.impl.criteria.AbstractFieldCriteriaHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.ebay.cloud.cms.dal.search.impl.criteria.AbstractFieldCriteriaHandler.java

Source

/*
Copyright [2013-2014] eBay Software Foundation
    
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    
http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/* 
Copyright 2012 eBay Software Foundation 
    
Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 
    
http://www.apache.org/licenses/LICENSE-2.0 
    
Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
See the License for the specific language governing permissions and 
limitations under the License. 
*/

package com.ebay.cloud.cms.dal.search.impl.criteria;

import java.util.ArrayList;
import java.util.List;

import com.ebay.cloud.cms.dal.search.ISearchField;
import com.ebay.cloud.cms.dal.search.impl.field.AbstractSearchField;
import com.ebay.cloud.cms.metadata.model.MetaField;
import com.ebay.cloud.cms.metadata.model.MetaField.CardinalityEnum;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public abstract class AbstractFieldCriteriaHandler implements IFieldCriteriaHandler {

    /**
     * Build query objects
     * 
     * @param criteria
     * @param query
     * @param atomQueryObject
     * @param checkFieldArray -- when the field on the criteria, decide to use $elemMatch or not. A couple of 
     */
    protected void buildCriteria(FieldSearchCriteria criteria, DBObject query, DBObject atomQueryObject) {
        String fullDbName = criteria.getFullDbName();
        ISearchField searchField = criteria.getSearchField();
        if (!(searchField instanceof AbstractSearchField)) {
            // GroupField : won't be array
            // AggregationField : won't be array
            query.put(fullDbName, atomQueryObject);
            return;
        }

        // AbstractSearchField
        AbstractSearchField asf = (AbstractSearchField) criteria.getSearchField();
        MetaField metaField = asf.getRootField();
        // inner property is an primitive type
        // embed handling : FIXME:: what about multiple layer of embedded(MANY)? We support only one layer of array for now
        String eleMatchName = asf.getRootFieldDbName();
        String innerField = asf.getInnerField();
        // 1. embed many
        if (criteria.isEmbeddedCardinalityMany() && criteria.isEmbeddedObject() && asf.getInnerProperty() == null) {
            // embed array
            String embedPath = asf.getEmbedPath();
            String parentPath = embedPath.substring(0, embedPath.length() - 1);
            String key = asf.getRootFieldDbName();
            if (useElemMatchName()) {
                key = asf.getRootFieldElemMatchDbName();
            }
            query.put(parentPath, new BasicDBObject("$elemMatch", new BasicDBObject(key, atomQueryObject)));
            return;
        }

        // 2. for cardinality=MANY case
        if (useArrayElemMatch() && asf.getInnerProperty() == null
                && metaField.getCardinality() == CardinalityEnum.Many) {
            if (criteria.isEmbeddedObject()) {
                String embedPath = asf.getEmbedPath();
                eleMatchName = embedPath + asf.getRootFieldDbName();
            }
            // add $elemMatch query object
            if (innerField == null) {
                query.put(eleMatchName, new BasicDBObject("$elemMatch", atomQueryObject));
            } else {
                query.put(eleMatchName,
                        new BasicDBObject("$elemMatch", new BasicDBObject(innerField, atomQueryObject)));
            }
            return;
        }

        // 3. if not array handling, this is the default behavior
        query.put(fullDbName, atomQueryObject);
    }

    protected DBObject buildNegativeArrayCriteria(FieldSearchCriteria criteria, DBObject query) {
        String fullDbName = criteria.getFullDbName();
        ISearchField searchField = criteria.getSearchField();
        if (!(searchField instanceof AbstractSearchField)) {
            // GroupField : won't be array
            // AggregationField : won't be array
            return query;
        }

        AbstractSearchField asf = (AbstractSearchField) criteria.getSearchField();
        MetaField metaField = asf.getRootField();
        if (useArrayElemMatch() && asf.getInnerProperty() == null
                && metaField.getCardinality() == CardinalityEnum.Many) {
            // for array of not, $elemMatch will force the $exists=true.
            BasicDBObject or = new BasicDBObject();
            List<DBObject> ors = new ArrayList<DBObject>();
            // exists
            ors.add(new BasicDBObject(fullDbName, new BasicDBObject("$exists", false)));
            ors.add(new BasicDBObject(fullDbName, new BasicDBObject("$size", 0)));
            ors.add(query);
            or.put("$or", ors);
            return or;
        }
        return query;
    }

    protected abstract boolean useArrayElemMatch();

    protected boolean useElemMatchName() {
        return true;
    }

}