All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tinygroup.mongodb.engine.view.MongoViewContext Maven / Gradle / Ivy

The newest version!
/**
 *  Copyright (c) 1997-2013, tinygroup.org ([email protected]).
 *
 *  Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html
 *
 *  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.
 * --------------------------------------------------------------------------
 *  版权 (c) 1997-2013, tinygroup.org ([email protected]).
 *
 *  本开源软件遵循 GPL 3.0 协议;
 *  如果您不遵循此协议,则不被允许使用此文件。
 *  你可以从下面的地址获取完整的协议文本
 *
 *       http://www.gnu.org/licenses/gpl.html
 */
package org.tinygroup.mongodb.engine.view;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.BSONObject;
import org.tinygroup.commons.tools.CollectionUtil;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.context.Context;
import org.tinygroup.imda.processor.ParameterBuilder;
import org.tinygroup.mongodb.common.ConditionField;
import org.tinygroup.mongodb.common.DisplayField;
import org.tinygroup.mongodb.common.Field;
import org.tinygroup.mongodb.common.GroupField;
import org.tinygroup.mongodb.common.HavingField;
import org.tinygroup.mongodb.common.MongoRelation;
import org.tinygroup.mongodb.common.ObjectField;
import org.tinygroup.mongodb.common.OrderField;
import org.tinygroup.mongodb.common.RelationCondition;
import org.tinygroup.mongodb.common.View;
import org.tinygroup.mongodb.common.ViewGroup;
import org.tinygroup.mongodb.engine.MongoDbContext;
import org.tinygroup.mongodb.engine.MongoField;
import org.tinygroup.mongodb.engine.PageInfo;
import org.tinygroup.mongodb.engine.view.extendinfo.FieldMaps;
import org.tinygroup.mongodb.engine.view.tree.TreeViewParamterBuilder;
import org.tinygroup.mongodb.model.MongoDBModel;
import org.tinygroup.mongodb.util.ModelUtil;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

/**
 * 
 * 功能说明: 视图的上下文
 * 

* 开发人员: renhui
* 开发时间: 2013-11-27
*
*/ public class MongoViewContext extends MongoDbContext { private View view; private List statistics = new ArrayList(); private Map mongoRelations = new HashMap(); private DBObject displayObject; private DBObject groupObject; private String nestedObject;// 保存嵌套对象的属性 public MongoViewContext(MongoDBModel model, View view, Context context) { super(model, context); this.view = view; displayObject = generateDisplayObject(); groupObject = generateGroupObject(); List relations = view.getRelations(); for (MongoRelation mongoRelation : relations) { List conditions = mongoRelation.getConditions(); for (RelationCondition condition : conditions) { String sourceRelationField = condition.getSourceRelationField(); MongoField field = getMongoField(sourceRelationField); String objectFieldName = null; ObjectField of = field.getObjectField(); if (of != null) { objectFieldName = of.getName(); } String sourcePropertyName = field.getField().getName(); String targetRelationField = condition.getTargetRelationField(); mongoRelations.put(sourcePropertyName, new MongoRelationData( objectFieldName, sourcePropertyName, targetRelationField, mongoRelation)); } } } public PageInfo queryMongoModel() { if (view != null) { DBObject conditionObject = generateConditionObject(); DBObject havingObject = generateHavingConditionObject(); DBObject orderObject = generateOrderObject(); int pageSize = checkPageSize(); String pageNumStr = context.get(ParameterBuilder.PAGE_NUMBER); int pageNum = 1; if (pageNumStr != null) { pageNum = Integer.parseInt(pageNumStr); } PageInfo pageInfo = persistence.find(displayObject, conditionObject, groupObject, havingObject, orderObject, pageNum, pageSize); // 查询数组时返回记录不会过滤不符合条件的数组记录,需要进行代码过滤掉 BSONObject[] records = pageInfo.getObjects(); if (records != null) { for (BSONObject record : records) { filterArrayRecords(record); } } return pageInfo; } return null; } /** * * 根据嵌套数组的条件,过滤生成符合的记录 * * @param records */ private void filterArrayRecords(BSONObject record) { List conditionFields = view.getConditionFields(); for (ConditionField conditionField : conditionFields) { MongoField mongoField = getMongoField(conditionField.getFieldId()); ObjectField of = mongoField.getObjectField(); String fieldName = mongoField.getField().getName(); if (of != null) { if (of.isArray()) { String propertyName = mongoField.getFieldName(); Object value = context.get(propertyName); if (value != null) {// 参数值为null不在从数组字段过滤结果集 Object itemArray = record.get(of.getName());// 数组字段 if (itemArray != null) { BasicDBList newList = new BasicDBList(); if (itemArray instanceof BasicDBList) { BasicDBList itemList = (BasicDBList) itemArray; for (Object item : itemList) { BSONObject itemRecord = (BSONObject) item; if (itemRecord.get(fieldName).equals(value)) { newList.add(itemRecord); } } record.put(of.getName(), newList); } } } } } } } /** * * 文档中嵌套数组对象的分页 * * @return */ public PageInfo nestedArrayQuery() { PageInfo pageInfo = new PageInfo(); int pageSize = checkPageSize(); String pageNumStr = context.get(ParameterBuilder.PAGE_NUMBER); int pageNum = 1; if (pageNumStr != null) { pageNum = Integer.parseInt(pageNumStr); } int size = 0; if (view != null) { DBObject conditionObject = generateConditionObject(); DBObject havingObject = generateHavingConditionObject(); DBObject orderObject = generateOrderObject(); DBObject displayObject = generateNestedDisplayObject(); BSONObject[] records = persistence.find(displayObject, conditionObject, groupObject, havingObject, orderObject); if (records != null && records.length == 1) { BSONObject record = records[0]; filterArrayRecords(record);// 根据嵌套字段条件进行过滤 Object object = record.get(nestedObject); if (object != null) { if (object instanceof BasicDBList) { BasicDBList nestedObjects = (BasicDBList) object; size = nestedObjects.size(); pageInfo.pageAttributeSet(pageSize, pageNum, size); int start = pageInfo.getStart(); int length = start + pageInfo.getPageSize(); int pageLength = pageInfo.getPageSize(); ; if (size < length) { pageLength = size - start; } BSONObject[] pageObjects = new BSONObject[pageLength]; for (int i = start, j = 0; j < pageLength; i++, j++) { BSONObject bsonObject = (BSONObject) nestedObjects .get(i); pageObjects[j] = bsonObject; } pageInfo.setObjects(pageObjects); return pageInfo; } } } else { pageInfo.pageAttributeSet(pageSize, pageNum, size); pageInfo.setObjects(new BSONObject[0]); } } return pageInfo; } /** * * 关联查询 * * @return */ public PageInfo relationQueryMongoModel() { if (view != null) { BSONObject[] records = getRecords(); if (records != null) { List bsonObjects = new ArrayList(); for (BSONObject record : records) { List objects = new ArrayList(); boolean first = true; for (String propertyName : mongoRelations.keySet()) { if (first) { BSONObject object = new BasicDBObject(); object.putAll(record); objects.add(object); first = false; } MongoRelationData data = mongoRelations .get(propertyName); objects = data.generateObjects(objects); } bsonObjects.addAll(objects); } int pageSize = checkPageSize(); String pageNumStr = context.get(ParameterBuilder.PAGE_NUMBER); int pageNum = 1; if (pageNumStr != null) { pageNum = Integer.parseInt(pageNumStr); } int size = bsonObjects.size(); PageInfo pageInfo = new PageInfo(); pageInfo.pageAttributeSet(pageSize, pageNum, size); int start = pageInfo.getStart(); int length = start + pageInfo.getPageSize(); int pageLength = pageInfo.getPageSize(); if (size < length) { pageLength = size - start; } BSONObject[] pageObjects = new BSONObject[pageLength]; for (int i = start, j = 0; j < pageLength; i++, j++) { BSONObject bsonObject = bsonObjects.get(i); pageObjects[j] = bsonObject; } pageInfo.setObjects(pageObjects); return pageInfo; } } return null; } private int checkPageSize() { String pageSizeStr = context.get(ParameterBuilder.PAGE_SIZE); int pageSize = 0; if (view.isFrontPaging()) {// 如果是前台分页,则返回0 return 0; } if (pageSizeStr == null) { pageSize = view.getPageSize(); } else { pageSize = Integer.parseInt(pageSizeStr); } return pageSize; } /** * * 树查询 * * @param * @param clazz * @return */ @SuppressWarnings("unchecked") public T[] queryMongoModelOfTree(Class clazz) { if (view != null) { BSONObject[] records = getRecords(); if (records != null) { String queryAll = context .get(TreeViewParamterBuilder.QUERY_ALL_TREE); FieldMaps maps = new FieldMaps(this, context); maps.parserExtendInfos(view.getExtendInformation()); T[] treeNodes = (T[]) Array.newInstance(clazz, records.length); for (int i = 0; i < records.length; i++) { if (!StringUtil.isBlank(queryAll) && queryAll.equals("true")) { BSONObject[] subRecords = getSubRecords(records[i]); treeNodes[i] = maps.object2TreeNodeWithRecursive( records[i], subRecords, clazz); } else { treeNodes[i] = maps.object2TreeNode(records[i], clazz); } } return treeNodes; } } return null; } private BSONObject[] getRecords() { DBObject conditionObject = generateConditionObject(); DBObject havingObject = generateHavingConditionObject(); DBObject orderObject = generateOrderObject(); BSONObject[] records = persistence.find(displayObject, conditionObject, groupObject, havingObject, orderObject); return records; } public BSONObject[] getSubRecords(BSONObject bsonObject) { contextReplace(bsonObject); return getRecords(); } /** * * 改变参数值 * * @param bsonObject */ private void contextReplace(BSONObject bsonObject) { List conditionFields = view.getConditionFields(); for (ConditionField conditionField : conditionFields) { String propertyName = getFieldName(conditionField.getFieldId()); if (bsonObject.containsField(propertyName)) { Object value = bsonObject.get(propertyName); context.put(propertyName, value); } } } /** * * view的参数组装 * * @param newContext * @param conditionFields * @return */ public Context buildConditionParameter(Context newContext, List conditionFields) { super.buildConditionFieldParamter(conditionFields, newContext); if (view.getHavingFields() != null) { for (HavingField havingField : view.getHavingFields()) { processHavingParamter(havingField, newContext); } } return newContext; } public DBObject generateDisplayObject() { List viewGroups = view.getViewGroups(); if (viewGroups != null && viewGroups.size() > 0) { DBObject display = new BasicDBObject(); for (ViewGroup viewGroup : viewGroups) { List displayFields = viewGroup.getFields(); for (DisplayField displayField : displayFields) { MongoField field = getMongoField(displayField.getFieldId()); String propertyName = field.getFieldName(); String aggregateFunction = displayField .getAggregateFunction(); if (aggregateFunction != null) { statistics.add(displayField); } display.put(propertyName, 1); } } return display; } return null; } public DBObject generateNestedDisplayObject() { List viewGroups = view.getViewGroups(); if (viewGroups != null && viewGroups.size() > 0) { DBObject display = new BasicDBObject(); for (ViewGroup viewGroup : viewGroups) { List displayFields = viewGroup.getFields(); for (DisplayField displayField : displayFields) { MongoField field = getMongoField(displayField.getFieldId()); ObjectField of = field.getObjectField(); if (of != null) {// TODO 对是否是同一嵌套对象的验证 if (nestedObject == null) { nestedObject = of.getName(); } String propertyName = field.getFieldName(); display.put(propertyName, 1); } } } return display; } return null; } /** * * 生成view的条件BSONObject * * @return */ public DBObject generateConditionObject() { return generateConditionObject(view.getConditionFields()); } /** * * 生成view的having条件BSONObject * * @return */ public DBObject generateHavingConditionObject() { List conditionFields = new ArrayList(); conditionFields.addAll(view.getHavingFields()); return generateConditionObject(conditionFields); } /** * * 生成view的分组BSONObject * * @return */ public DBObject generateGroupObject() { List groupFields = view.getGroupFields(); if (!CollectionUtil.isEmpty(groupFields)) { BSONObject _group = new BasicDBObject(); for (GroupField groupField : groupFields) { MongoField field = getMongoField(groupField.getFieldId()); String propertyName = field.getFieldName(); _group.put(propertyName, "$" + propertyName); } DBObject objectFields = new BasicDBObject("_id", _group); for (DisplayField displayField : statistics) { MongoField field = getMongoField(displayField.getFieldId()); String propertyName = field.getFieldName(); String aggregateFunction = displayField.getAggregateFunction(); if (aggregateFunction != null) { objectFields.put(propertyName + aggregateFunction, new BasicDBObject("$" + aggregateFunction, "$" + propertyName)); } } return objectFields; } return null; } public DBObject generateOrderObject() { List orderFields = view.getOrderFields(); if (!CollectionUtil.isEmpty(orderFields)) { DBObject order = new BasicDBObject(); for (OrderField orderField : orderFields) { MongoField field = getMongoField(orderField.getFieldId()); String propertyName = field.getFieldName(); if (orderField.getOrderMode() != null && orderField.getOrderMode().equals(DESC)) { order.put(propertyName, -1); } else { order.put(propertyName, 1); } } return order; } return null; } private void processHavingParamter(HavingField havingField, Context newContext) { Field field = getField(havingField.getFieldId()); String propertyName = field.getName(); String paramName = ModelUtil.getSpliceParamterName(propertyName, HAVING_FIELD); Object value = context.get(paramName); if (value == null) { if (havingField.isHidden()) { value = field.getDefaultValue(); } } if (value != null) { newContext.put(paramName, value); } String compareParamterName = ModelUtil.getSpliceParamterName( propertyName, HAVING_COMPARE_MODE); Object compareModeValue = context.get(compareParamterName); if (compareModeValue != null) { newContext.put(compareParamterName, compareModeValue); } } public boolean hasGroupByField() { return !CollectionUtil.isEmpty(view.getGroupFields()); } public boolean hasHavingField() { return !CollectionUtil.isEmpty(view.getHavingFields()); } public boolean hasOrderField() { return !CollectionUtil.isEmpty(view.getOrderFields()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy