// // 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.regex.Pattern; import org.apache.commons.lang.StringUtils; 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; /** * Singleton to manage our access to the user collection in our mongoDB * * @author vibul * */ public class UserController extends Controller { public static final String MONGODB_COLLECTION_NAME = "users"; /** * Returns the singleton instance for this class */ public static UserController getInstance() { return SingletonHolder.INSTANCE; } /** * SingletonHolder is loaded on the first execution of Singleton.getInstance() or the first access to * SingletonHolder.INSTANCE, not before. * * @see http://en.wikipedia.org/wiki/Singleton_pattern */ private static class SingletonHolder { public static final UserController INSTANCE = new UserController(); } /** * <p> * Singleton constructor * </p> */ private UserController() { return; } /** * Returns the name of the mongoDB collection for this business object */ @Override protected String getDBCollectionName() { return MONGODB_COLLECTION_NAME; } /** * Retrieves the specified user by the id * * @param db * mongoDB connection * @param id * unique id for the document stored in mongoDB * @return code>UserBO</code> representing the user * @throws ChiliLogException * if not found or database error */ public UserBO get(DB db, ObjectId id) throws ChiliLogException { UserBO o = tryGet(db, id); if (o == null) { throw new ChiliLogException(Strings.USER_NOT_FOUND_ERROR, id.toString()); } return o; } /** * Tries to retrieve the specified user 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>UserBO</code> representing the user or null if user is not found * @throws ChiliLogException * if database or data error */ public UserBO 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(MONGODB_COLLECTION_NAME); BasicDBObject condition = new BasicDBObject(); condition.put(BO.DOCUMENT_ID_FIELD_NAME, id); DBObject dbo = coll.findOne(condition); if (dbo == null) { return null; } return new UserBO(dbo); } catch (MongoException ex) { throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage()); } } /** * Retrieves the specified user by the username * * @param db * mongoDB connection * @param username * username of user to retrieve * @return code>UserBO</code> representing the user * @throws ChiliLogException * if not found or database error */ public UserBO getByUsername(DB db, String username) throws ChiliLogException { UserBO o = tryGetByUsername(db, username); if (o == null) { throw new ChiliLogException(Strings.USER_NOT_FOUND_ERROR, username); } return o; } /** * Tries to retrieve the specified user by the username. If not found, null is returned. * * @param db * mongoDB connection * @param username * username of user to retrieve * @return <code>UserBO</code> representing the user or null if user is not found * @throws ChiliLogException * if database or data error */ public UserBO tryGetByUsername(DB db, String username) throws ChiliLogException { try { if (db == null) { throw new IllegalArgumentException("db cannot be null"); } if (StringUtils.isBlank(username)) { throw new IllegalArgumentException("username cannot be blank"); } DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME); BasicDBObject query = new BasicDBObject(); query.put(UserBO.USERNAME_FIELD_NAME, username); DBObject dbo = coll.findOne(query); if (dbo == null) { return null; } return new UserBO(dbo); } catch (MongoException ex) { throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage()); } } /** * Retrieves the specified user by the email address * * @param db * mongoDB connection * @param emailAddress * Email address of user to retrieve * @return code>UserBO</code> representing the user * @throws ChiliLogException * if not found or database error */ public UserBO getByEmailAddress(DB db, String emailAddress) throws ChiliLogException { UserBO o = tryGetByEmailAddress(db, emailAddress); if (o == null) { throw new ChiliLogException(Strings.USER_NOT_FOUND_ERROR, emailAddress); } return o; } /** * Tries to retrieve the specified user by the email address. If not found, null is returned. * * @param db * mongoDB connection * @param emailAddress * Email address of user to retrieve * @return <code>UserBO</code> representing the user or null if user is not found * @throws ChiliLogException * if database or data error */ public UserBO tryGetByEmailAddress(DB db, String emailAddress) throws ChiliLogException { try { if (db == null) { throw new IllegalArgumentException("db cannot be null"); } if (StringUtils.isBlank(emailAddress)) { throw new IllegalArgumentException("emailAddress cannot be blank"); } DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME); BasicDBObject query = new BasicDBObject(); query.put(UserBO.EMAIL_ADDRESS_FIELD_NAME, emailAddress); DBObject dbo = coll.findOne(query); if (dbo == null) { return null; } return new UserBO(dbo); } catch (MongoException ex) { throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage()); } } /** * Get a list of users * * @param db * mongoDB connection * @param criteria * criteria to filter users * @return List of users matching the specified criteria * @throws ChiliLogException * if database or data error */ public ArrayList<UserBO> getList(DB db, UserListCriteria criteria) throws ChiliLogException { DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME); // Filter BasicDBObject condition = new BasicDBObject(); if (!StringUtils.isBlank(criteria.getUsernamePattern())) { Pattern pattern = Pattern.compile(criteria.getUsernamePattern()); condition.put(UserBO.USERNAME_FIELD_NAME, pattern); } if (!StringUtils.isBlank(criteria.getEmailAddressPattern())) { Pattern pattern = Pattern.compile(criteria.getEmailAddressPattern()); condition.put(UserBO.EMAIL_ADDRESS_FIELD_NAME, pattern); } if (!StringUtils.isBlank(criteria.getRole())) { condition.put(UserBO.ROLES_FIELD_NAME, criteria.getRole()); } if (!StringUtils.isBlank(criteria.getRolePattern())) { Pattern repositoryNameMatch = Pattern.compile(criteria.getRolePattern()); condition.put(UserBO.ROLES_FIELD_NAME, repositoryNameMatch); } if (criteria.getStatus() != null) { condition.put(UserBO.STATUS_FIELD_NAME, criteria.getStatus().toString()); } // Order DBObject orderBy = new BasicDBObject(); orderBy.put(UserBO.USERNAME_FIELD_NAME, 1); // Get matching records int recordsPerPage = criteria.getRecordsPerPage(); int skipDocumentCount = (criteria.getStartPage() - 1) * recordsPerPage; DBCursor cur = coll.find(condition).skip(skipDocumentCount).limit(recordsPerPage).sort(orderBy); ArrayList<UserBO> list = new ArrayList<UserBO>(); while (cur.hasNext()) { DBObject dbo = cur.next(); list.add(new UserBO(dbo)); } // Do page count by executing query again if (criteria.getDoPageCount()) { int documentCount = coll.find(condition).count(); criteria.calculatePageCount(documentCount); } return list; } /** * Saves the user into mongoDB * * @param db * MongoDb connection * @param user * User to save * @throws ChiliLogException * if there are errors */ public void save(DB db, UserBO user) throws ChiliLogException { // Validate unique username DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME); BasicDBObject condition = new BasicDBObject(); condition.put(UserBO.USERNAME_FIELD_NAME, user.getUsername()); if (user.isExistingRecord()) { condition.put(BO.DOCUMENT_ID_FIELD_NAME, new BasicDBObject("$ne", user.getDocumentID())); } long i = coll.getCount(condition); if (i > 0) { throw new ChiliLogException(Strings.USER_DUPLICATE_USERNAME_ERROR, user.getUsername()); } // Validate unique email address if (!StringUtils.isBlank(user.getEmailAddress())) { condition = new BasicDBObject(); condition.put(UserBO.EMAIL_ADDRESS_FIELD_NAME, user.getEmailAddress()); if (user.isExistingRecord()) { condition.put(BO.DOCUMENT_ID_FIELD_NAME, new BasicDBObject("$ne", user.getDocumentID())); } i = coll.getCount(condition); if (i > 0) { throw new ChiliLogException(Strings.USER_DUPLICATE_EMAIL_ADDRESS_ERROR, user.getEmailAddress()); } } // Save it super.save(db, user); } /** * Removes the specified user from mongoDB * * @param db * MongoDb connection * @param user * User to remove * @throws ChiliLogException * if there are errors */ public void remove(DB db, UserBO user) throws ChiliLogException { super.remove(db, user); } }