org.chililog.server.data.RepositoryConfigController.java Source code

Java tutorial

Introduction

Here is the source code for org.chililog.server.data.RepositoryConfigController.java

Source

//
// 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 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 repository configuration documents in our mongoDB
 * 
 * @author vibul
 * 
 */
public class RepositoryConfigController extends Controller {

    public static final String MONGODB_COLLECTION_NAME = "repo";

    /**
     * Returns the singleton instance for this class
     */
    public static RepositoryConfigController 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 RepositoryConfigController INSTANCE = new RepositoryConfigController();
    }

    /**
     * <p>
     * Singleton constructor
     * </p>
     */
    private RepositoryConfigController() {
        return;
    }

    /**
     * Returns the name of the mongoDB collection for this business object
     */
    @Override
    protected String getDBCollectionName() {
        return MONGODB_COLLECTION_NAME;
    }

    /**
     * Retrieves the specified repository by its id
     * 
     * @param db
     *            mongoDB connection
     * @param id
     *            unique id for the document stored in mongoDB
     * @return code>RepositoryInfoBO</code> representing the repository
     * @throws ChiliLogException
     *             if not found or database error
     */
    public RepositoryConfigBO get(DB db, ObjectId id) throws ChiliLogException {
        RepositoryConfigBO o = tryGet(db, id);
        if (o == null) {
            throw new ChiliLogException(Strings.REPO_INFO_NOT_FOUND_ERROR, id.toString());
        }
        return o;
    }

    /**
     * Tries to retrieve the specified repository by its id. If not found, null is returned.
     * 
     * @param db
     *            mongoDB connection
     * @param id
     *            unique id for the document stored in mongoDB
     * @return <code>RepositoryInfoBO</code> representing the repository or null if repository is not found
     * @throws ChiliLogException
     *             if database or data error
     */
    public RepositoryConfigBO 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 RepositoryConfigBO(dbo);
        } catch (MongoException ex) {
            throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
        }
    }

    /**
     * Retrieves the specified repository by its name
     * 
     * @param db
     *            mongoDB connection
     * @param name
     *            name of the repository to retrieve
     * @return code>RepositoryInfoBO</code> representing the repository
     * @throws ChiliLogException
     *             if not found or database error
     */
    public RepositoryConfigBO getByName(DB db, String name) throws ChiliLogException {
        RepositoryConfigBO o = tryGetByName(db, name);
        if (o == null) {
            throw new ChiliLogException(Strings.REPO_INFO_NOT_FOUND_ERROR, name);
        }
        return o;
    }

    /**
     * Tries to retrieve the specified repository by its name. If not found, null is returned.
     * 
     * @param db
     *            mongoDB connection
     * @param name
     *            name of repository to retrieve
     * @return <code>RepositoryInfoBO</code> representing the repository or null if repository is not found
     * @throws ChiliLogException
     *             if database or data error
     */
    public RepositoryConfigBO tryGetByName(DB db, String name) throws ChiliLogException {
        try {
            if (db == null) {
                throw new IllegalArgumentException("db cannot be null");
            }
            if (StringUtils.isBlank(name)) {
                throw new IllegalArgumentException("name cannot be blank");
            }

            DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME);
            BasicDBObject condition = new BasicDBObject();
            condition.put(RepositoryConfigBO.NAME_FIELD_NAME, name);
            DBObject dbo = coll.findOne(condition);
            if (dbo == null) {
                return null;
            }
            return new RepositoryConfigBO(dbo);
        } catch (MongoException ex) {
            throw new ChiliLogException(ex, Strings.MONGODB_QUERY_ERROR, ex.getMessage());
        }
    }

    /**
     * Get a list of all 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<RepositoryConfigBO> getList(DB db, RepositoryConfigListCriteria criteria)
            throws ChiliLogException {
        DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME);

        // Filter
        BasicDBObject condition = new BasicDBObject();
        if (!StringUtils.isBlank(criteria.getNamePattern())) {
            Pattern pattern = Pattern.compile(criteria.getNamePattern());
            condition.put(RepositoryConfigBO.NAME_FIELD_NAME, pattern);
        }
        if (criteria.getNameRestrictions() != null && criteria.getNameRestrictions().length > 0) {
            condition.put(RepositoryConfigBO.NAME_FIELD_NAME,
                    new BasicDBObject("$in", criteria.getNameRestrictions()));
        }

        // Order
        DBObject orderBy = new BasicDBObject();
        orderBy.put(RepositoryConfigBO.NAME_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<RepositoryConfigBO> list = new ArrayList<RepositoryConfigBO>();
        while (cur.hasNext()) {
            DBObject dbo = cur.next();
            list.add(new RepositoryConfigBO(dbo));
        }

        // Do page count by executing query again
        if (criteria.getDoPageCount()) {
            int documentCount = coll.find(condition).count();
            criteria.calculatePageCount(documentCount);
        }

        return list;
    }

    /**
     * Saves the repository into mongoDB
     * 
     * @param db
     *            MongoDb connection
     * @param repoConfig
     *            Repository configuration to save
     * @throws ChiliLogException
     *             if there are errors
     */
    public void save(DB db, RepositoryConfigBO repoConfig) throws ChiliLogException {
        // Validate unique name
        DBCollection coll = db.getCollection(MONGODB_COLLECTION_NAME);
        BasicDBObject condition = new BasicDBObject();
        condition.put(RepositoryConfigBO.NAME_FIELD_NAME, repoConfig.getName());
        if (repoConfig.isExistingRecord()) {
            condition.put(BO.DOCUMENT_ID_FIELD_NAME, new BasicDBObject("$ne", repoConfig.getDocumentID()));
        }
        long i = coll.getCount(condition);
        if (i > 0) {
            throw new ChiliLogException(Strings.REPO_INFO_DUPLICATE_NAME_ERROR, repoConfig.getName());
        }

        // Validate unique parser names
        for (RepositoryParserConfigBO p : repoConfig.getParsers()) {
            String parserName = p.getName();
            int pCount = 0;
            for (RepositoryParserConfigBO p2 : repoConfig.getParsers()) {
                if (p2.getName().equals(parserName)) {
                    pCount++;
                }
            }
            if (pCount != 1) {
                throw new ChiliLogException(Strings.REPO_INFO_DUPLICATE_PARSER_NAME_ERROR, parserName,
                        repoConfig.getName());
            }

            // Validate unique field names per parser
            for (RepositoryFieldConfigBO f : p.getFields()) {
                String fieldName = f.getName();
                int count = 0;
                for (RepositoryFieldConfigBO f2 : p.getFields()) {
                    if (f2.getName().equals(fieldName)) {
                        count++;
                    }
                }
                if (count != 1) {
                    throw new ChiliLogException(Strings.REPO_INFO_DUPLICATE_FIELD_NAME_ERROR, fieldName, parserName,
                            repoConfig.getName());
                }
            }
        }

        // Save it
        super.save(db, repoConfig);

        // Add repository and index
        createIndexes(db);
    }

    /**
     * Creates the required repository index
     * 
     * @param db
     *            Database connection
     */
    private void createIndexes(DB db) {
        DBCollection col = db.getCollection(this.getDBCollectionName());
        List<DBObject> indexes = col.getIndexInfo();

        boolean found = false;
        for (DBObject idx : indexes) {
            if (idx.get("name").equals("keyword_ts_index")) {
                found = true;
                break;
            }
        }
        if (!found) {
            BasicDBObject keys = new BasicDBObject();
            keys.put(RepositoryEntryBO.KEYWORDS_FIELD_NAME, 1);
            keys.put(RepositoryEntryBO.TIMESTAMP_FIELD_NAME, 1);
            col.ensureIndex(keys, "keyword_ts_index");
        }
    }

    /**
     * Removes the specified repository from mongoDB
     * 
     * @param db
     *            MongoDb connection
     * @param repoConfig
     *            User to remove
     * @throws ChiliLogException
     *             if there are errors
     */
    public void remove(DB db, RepositoryConfigBO repoConfig) throws ChiliLogException {
        super.remove(db, repoConfig);
    }
}