//
// Copyright 2010 Cinch Logic Pty Ltd.
//
// http://www.chililog.com
//
// 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 org.chililog.server.data;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.NullArgumentException;
import org.bson.types.ObjectId;
import org.chililog.server.common.ChiliLogException;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
/**
* <p>
* Controller to read and write repository entries
* </p>
*
* @author vibul
*
*/
public class RepositoryEntryController extends Controller {
private RepositoryConfigBO _repoInfo = null;
private String _mongoDBCollectionName = null;
/**
* Returns an instance of the repository entry controller to use.
*
* @param repoInfo
* Meta data for the repository to which we will be reading and writing
* @return RepositoryEntryController
*/
public static RepositoryEntryController getInstance(RepositoryConfigBO repoInfo) {
// TODO cache entry controllers
return new RepositoryEntryController(repoInfo);
}
/**
* Basic constructor
*
* @param repoInfo
* Repository info
*/
RepositoryEntryController(RepositoryConfigBO repoInfo) {
_repoInfo = repoInfo;
_mongoDBCollectionName = repoInfo.getMongoDBCollectionName();
}
/**
* Returns the mongoDB collection name
*/
@Override
protected String getDBCollectionName() {
return _mongoDBCollectionName;
}
/**
* Returns the meta data of the repository to which we will be reading and writing
*/
public RepositoryConfigBO getRepoInfo() {
return _repoInfo;
}
/**
* Retrieves the specified entry by the id
*
* @param db
* mongoDB connection
* @param id
* unique id for the document stored in mongoDB
* @return code>RepositoryEntryBO</code> representing the user
* @throws ChiliLogException
* if not found or database error
*/
public RepositoryEntryBO get(DB db, ObjectId id) throws ChiliLogException {
RepositoryEntryBO o = tryGet(db, id);
if (o == null) {
throw new ChiliLogException(Strings.USER_NOT_FOUND_ERROR, id.toString());
}
return o;
}
/**
* Tries to retrieve the specified entry by the id. If not found, null is returned.
*
* @param db
* mongoDB connection
* @param id
* unique id for the document stored in mongoDB
* @return <code>RepositoryEntryBO</code> representing the user or null if user is not found
* @throws ChiliLogException
* if database or data error
*/
public RepositoryEntryBO tryGet(DB db, ObjectId id) throws ChiliLogException {
try {
if (db == null) {
throw new IllegalArgumentException("db cannot be null");
}
if (id == null) {
throw new IllegalArgumentException("id cannot be null");
}
DBCollection coll = db.getCollection(this.getDBCollectionName());
BasicDBObject condition = new BasicDBObject();
condition.put(BO.DOCUMENT_ID_FIELD_NAME, id);
DBObject dbo = coll.findOne(condition);
if (dbo == null) {
return null;
}
return new RepositoryEntryBO(dbo);
} catch (MongoException ex) {
throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
}
}
/**
* Returns a list of matching entries
*
* @param db
* Database connection
* @param criteria
* Criteria to filter resultset
* @return List of matching entries
* @throws ChiliLogException
*/
public ArrayList<RepositoryEntryBO> getList(DB db, RepositoryEntryListCriteria criteria) throws ChiliLogException {
ArrayList<DBObject> list = executeFindQuery(db, criteria);
ArrayList<RepositoryEntryBO> boList = new ArrayList<RepositoryEntryBO>();
if (list != null && !list.isEmpty()) {
for (DBObject o : list) {
boList.add(new RepositoryEntryBO(o));
}
}
return boList;
}
/**
* Find matching entries
*
* @param db
* Database connection
* @param criteria
* Criteria to filter resultset. Fields, conditions and orderby are used.
* @return List of matching entries
*/
public ArrayList<DBObject> executeFindQuery(DB db, RepositoryEntryListCriteria criteria) throws ChiliLogException {
try {
if (db == null) {
throw new NullArgumentException("db");
}
if (criteria == null) {
throw new NullArgumentException("criteria");
}
DBCollection coll = db.getCollection(this.getDBCollectionName());
int recordsPerPage = criteria.getRecordsPerPage();
int skipDocumentCount = (criteria.getStartPage() - 1) * recordsPerPage;
DBObject fields = criteria.getFieldsDbObject();
DBObject conditions = criteria.getConditionsDbObject();
DBObject orderBy = criteria.getOrderByDbObject();
DBCursor cur = coll.find(conditions, fields).skip(skipDocumentCount).limit(recordsPerPage).sort(orderBy);
ArrayList<DBObject> list = new ArrayList<DBObject>();
while (cur.hasNext()) {
DBObject dbo = cur.next();
list.add(dbo);
}
// Do page count by executing query again
if (criteria.getDoPageCount()) {
int documentCount = coll.find(conditions).count();
criteria.calculatePageCount(documentCount);
}
return list;
} catch (Exception ex) {
throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
}
}
/**
* Count of number of entries that matches the condition
*
* @param db
* Database connection
* @param criteria
* Criteria to filter resultset. Condition is used.
* @return Number of matching entries
*/
public int executeCountQuery(DB db, RepositoryEntryListCriteria criteria) throws ChiliLogException {
try {
if (db == null) {
throw new NullArgumentException("db");
}
if (criteria == null) {
throw new NullArgumentException("criteria");
}
DBCollection coll = db.getCollection(this.getDBCollectionName());
DBObject conditions = criteria.getConditionsDbObject();
return coll.find(conditions).count();
} catch (Exception ex) {
throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
}
}
/**
* Count of number of entries that matches the condition
*
* @param db
* Database connection
* @param criteria
* Criteria to filter resultset. Fields and Conditions is used.
* @return List of distinct values for the nominated field.
*/
@SuppressWarnings("rawtypes")
public List executeDistinctQuery(DB db, RepositoryEntryListCriteria criteria) throws ChiliLogException {
try {
if (db == null) {
throw new NullArgumentException("db");
}
if (criteria == null) {
throw new NullArgumentException("criteria");
}
DBCollection coll = db.getCollection(this.getDBCollectionName());
DBObject fields = criteria.getFieldsDbObject();
if (fields == null || fields.keySet().isEmpty()) {
throw new IllegalArgumentException("Field is required for a 'distinct' query.");
}
String fieldName = null;
for (String n : fields.keySet()) {
fieldName = n;
break;
}
DBObject conditions = criteria.getConditionsDbObject();
return coll.distinct(fieldName, conditions);
} catch (Exception ex) {
throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
}
}
/**
* Count of number of entries that matches the condition
*
* @param db
* Database connection
* @param criteria
* Criteria to filter resultset. Fields, Conditions, Initial, ReduceFunction and FinalizeFunction are
* used.
* @return Specified fields and aggregation counter.
*/
public DBObject executeGroupQuery(DB db, RepositoryEntryListCriteria criteria) throws ChiliLogException {
try {
if (db == null) {
throw new NullArgumentException("db");
}
if (criteria == null) {
throw new NullArgumentException("criteria");
}
DBCollection coll = db.getCollection(this.getDBCollectionName());
DBObject fields = criteria.getFieldsDbObject();
DBObject conditions = criteria.getConditionsDbObject();
DBObject initial = criteria.getIntialDbObject();
return coll
.group(fields, conditions, initial, criteria.getReduceFunction(), criteria.getFinalizeFunction());
} catch (Exception ex) {
throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
}
}
/**
* Saves the repository entry into mongoDB
*
* @param db
* MongoDb connection
* @param entry
* Entry to save
* @throws ChiliLogException
* if there are errors
*/
public void save(DB db, RepositoryEntryBO entry) throws ChiliLogException {
// Save it
super.save(db, entry);
}
/**
* Removes the specified repository entry from mongoDB
*
* @param db
* MongoDb connection
* @param entry
* Entry to remove
* @throws ChiliLogException
* if there are errors
*/
public void remove(DB db, RepositoryEntryBO entry) throws ChiliLogException {
super.remove(db, entry);
}
}