Java tutorial
/******************************************************************************* * Copyright (c) 2011 Bryan Hunt and Ed Merks. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bryan Hunt and Ed Merks - initial API and implementation *******************************************************************************/ package org.eclipselabs.mongoemf.query.simple; import java.util.ArrayList; import java.util.List; import org.bson.types.ObjectId; import org.eclipse.emf.common.util.URI; import org.eclipselabs.emodeling.query.BinaryOperation; import org.eclipselabs.emodeling.query.Expression; import org.eclipselabs.emodeling.query.Literal; import org.eclipselabs.emodeling.query.util.ExpressionBuilder; import org.eclipselabs.emodeling.query.util.QuerySwitch; import org.eclipselabs.mongoemf.Keywords; import org.eclipselabs.mongoemf.QueryEngine; import org.eclipselabs.mongoemf.model.ModelFactory; import org.eclipselabs.mongoemf.model.MongoQuery; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.QueryOperators; /** * @author merks * */ public class SimpleQueryEngine implements QueryEngine { @Override public MongoQuery buildDBObjectQuery(URI uri) { MongoQuery mongoQuery = ModelFactory.eINSTANCE.createMongoQuery(); mongoQuery.setFilter(buildDBObjectQuery(new ExpressionBuilder(URI.decode(uri.query())).parseExpression())); return mongoQuery; } private DBObject buildDBObjectQuery(Expression expression) { final DBObject dbObject = new BasicDBObject(); if (expression != null) { new QuerySwitch<Object>() { Object getValue(Literal literal) { return literal.getValue() == null ? literal.getLiteralValue() : literal.getValue(); } @Override public Object caseBinaryOperation(BinaryOperation binaryOperation) { Expression leftOperand = binaryOperation.getLeftOperand(); String operator = binaryOperation.getOperator(); if ("==".equals(operator)) { Expression rightOperand = binaryOperation.getRightOperand(); String property = ExpressionBuilder.toString(leftOperand); if (Keywords.ID_KEY.equals(property)) { dbObject.put(property, new ObjectId(((Literal) rightOperand).getLiteralValue())); } else if (rightOperand instanceof Literal) { dbObject.put(property, getValue((Literal) rightOperand)); } else if ("null".equals(ExpressionBuilder.toString(rightOperand))) { DBObject notExists = new BasicDBObject(); notExists.put("$exists", Boolean.FALSE); dbObject.put(property, notExists); } else { // TODO: What to do? } } else if ("!=".equals(operator)) { Expression rightOperand = binaryOperation.getRightOperand(); String property = ExpressionBuilder.toString(leftOperand); if (rightOperand instanceof Literal) { DBObject notEqual = new BasicDBObject(); notEqual.put("$ne", getValue((Literal) rightOperand)); dbObject.put(property, notEqual); } else if ("null".equals(ExpressionBuilder.toString(rightOperand))) { DBObject exists = new BasicDBObject(); exists.put("$exists", Boolean.TRUE); dbObject.put(property, exists); } else { // TODO: What to do? } } else if ("<".equals(operator) || "<=".equals(operator) || ">".equals(operator) || ">=".equals(operator)) { Expression rightOperand = binaryOperation.getRightOperand(); String property = ExpressionBuilder.toString(leftOperand); if (rightOperand instanceof Literal) { DBObject compare = new BasicDBObject(); compare.put( "<".equals(operator) ? QueryOperators.LT : "<=".equals(operator) ? QueryOperators.LTE : ">".equals(operator) ? QueryOperators.GT : QueryOperators.GTE, getValue((Literal) rightOperand)); dbObject.put(property, compare); } else { // TODO: What to do? } } else if ("||".equals(operator)) { DBObject leftObject = buildDBObjectQuery(leftOperand); DBObject rightObject = buildDBObjectQuery(binaryOperation.getRightOperand()); @SuppressWarnings("unchecked") List<Object> or = (List<Object>) leftObject.get("$or"); if (or != null) { or.add(rightObject); dbObject.putAll(leftObject); } else { or = new ArrayList<Object>(); or.add(leftObject); or.add(rightObject); dbObject.put("$or", or); } } else if ("&&".equals(operator)) { dbObject.putAll(buildDBObjectQuery(leftOperand)); DBObject rightObject = buildDBObjectQuery(binaryOperation.getRightOperand()); for (String field : rightObject.keySet()) { Object rightValue = rightObject.get(field); Object leftValue = dbObject.get(field); if (leftValue instanceof DBObject) { DBObject leftDBObject = (DBObject) leftValue; if (rightValue instanceof DBObject) { DBObject rightDBObject = (DBObject) rightValue; if (leftDBObject.containsField("$nin") && rightDBObject.containsField("$ne")) { @SuppressWarnings("unchecked") List<Object> values = (List<Object>) leftDBObject.get("$nin"); values.add(rightDBObject.get("$ne")); } else if (leftDBObject.containsField("$ne") && rightDBObject.containsField("$ne")) { DBObject nin = new BasicDBObject(); List<Object> values = new ArrayList<Object>(); values.add(leftDBObject.get("$ne")); values.add(rightDBObject.get("$ne")); nin.put("$nin", values); dbObject.put(field, nin); } else { leftDBObject.putAll(rightDBObject); } } else { Object all = leftDBObject.get("$all"); if (all instanceof List<?>) { @SuppressWarnings("unchecked") List<Object> allList = (List<Object>) all; allList.add(rightValue); } else { // What to do? } } } else if (leftValue instanceof List<?>) { @SuppressWarnings("unchecked") List<Object> leftListValue = (List<Object>) leftValue; if (rightValue instanceof List<?>) { leftListValue.addAll((List<?>) rightValue); } else { leftListValue.add(rightValue); } } else if (leftValue != null) { if (rightValue instanceof List<?>) { @SuppressWarnings("unchecked") List<Object> rightListValue = (List<Object>) rightValue; rightListValue.add(0, leftValue); dbObject.put(field, rightListValue); } else { List<Object> listValue = new ArrayList<Object>(); listValue.add(leftValue); listValue.add(rightValue); DBObject in = new BasicDBObject("$all", listValue); dbObject.put(field, in); } } else { dbObject.put(field, rightValue); } } } return null; } }.doSwitch(expression); } return dbObject; } }