org.openntf.xpt.core.dss.AbstractStorageService.java Source code

Java tutorial

Introduction

Here is the source code for org.openntf.xpt.core.dss.AbstractStorageService.java

Source

/*
 *  Copyright WebGate Consulting AG, 2013
 * 
 * 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.
 */

/*
 * Special Thank to Matthias Cullmann and Sven Haufe for the inspiration of this class
 */

package org.openntf.xpt.core.dss;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.DocumentCollection;
import lotus.domino.View;

import org.apache.commons.collections.CollectionUtils;
import org.openntf.xpt.core.XPTRuntimeException;
import org.openntf.xpt.core.dss.changeLog.ChangeLogEntry;
import org.openntf.xpt.core.dss.changeLog.ChangeLogService;
import org.openntf.xpt.core.utils.RoleAndGroupProvider;
import org.openntf.xpt.core.utils.logging.LoggerFactory;

import com.ibm.xsp.extlib.util.ExtLibUtil;

/**
 * Abstract class with all methode's for a storage service.
 * 
 * You need to define the createObject() to build the object for T
 * 
 * @author Christian Guedemann
 * 
 * @param <T>
 *            The Type of the Object you want to load/store
 */
public abstract class AbstractStorageService<T> {

    protected AbstractStorageService() {
    }

    /**
     * Stores the object in the current database.
     * 
     * @param obj
     *            The object to store
     * @return true if the save operation was successful
     */

    public boolean save(T obj) {
        return saveTo(obj, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Stores the objec in the target database.
     * 
     * @param obj
     *            the object to store
     * @param targetDatabase
     *            the target database
     * @return true if the save operation was successful
     */
    public boolean saveTo(T obj, Database targetDatabase) {
        try {
            return DominoStorageService.getInstance().saveObject(obj, targetDatabase);
        } catch (DSSException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Loads an object from the current database
     * 
     * @param id
     * @return the object
     */
    public T getById(String id) {
        return getByIdFrom(id, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Load an object form the source database
     * 
     * @param id
     * @param sourceDatabase
     * @return the object
     */
    public T getByIdFrom(String id, Database sourceDatabase) {
        try {
            T ret = createObject();
            if (!DominoStorageService.getInstance().getObject(ret, id, sourceDatabase)) {
                return null;
            }
            return ret;
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
    }

    /**
     * Loads all objects from a view
     * 
     * @param viewName
     * @return List of objects
     */
    public List<T> getAll(String viewName) {
        return getAllFrom(viewName, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Loads all objects form a view from the source database
     * 
     * @param viewName
     * @param sourceDatabase
     * @return
     */
    public List<T> getAllFrom(String viewName, Database sourceDatabase) {
        List<T> ret = new ArrayList<T>();
        try {
            View viwDabases = sourceDatabase.getView(viewName);
            viwDabases.setAutoUpdate(false);
            Document docNext = viwDabases.getFirstDocument();
            while (docNext != null) {
                Document docCurrent = docNext;
                docNext = viwDabases.getNextDocument(docNext);
                convertDocument2ObjectAndAdd2List(ret, docCurrent);
                docCurrent.recycle();

            }
            viwDabases.recycle();
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return ret;
    }

    /**
     * Loads all object by a foreign id from a view
     * 
     * @param foreignId
     * @param viewName
     * @return List with object
     */
    public List<T> getObjectsByForeignId(String foreignId, String viewName) {
        return getObjectsByForeignIdFrom(foreignId, viewName, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Load all objects by a foreign id form a view from the source database
     * 
     * @param foreignId
     * @param viewName
     * @param sourceDatabase
     * @return
     */
    public List<T> getObjectsByForeignIdFrom(String foreignId, String viewName, Database sourceDatabase) {
        List<T> ret = new ArrayList<T>();
        try {
            View view = sourceDatabase.getView(viewName);
            view.setAutoUpdate(false);
            DocumentCollection documents = view.getAllDocumentsByKey(foreignId, true);
            Document docNext = documents.getFirstDocument();
            while (docNext != null) {
                Document docCurrent = docNext;
                docNext = documents.getNextDocument(docNext);

                convertDocument2ObjectAndAdd2List(ret, docCurrent);
                docCurrent.recycle();

            }
            view.recycle();
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return ret;
    }

    /**
     * Loads all object where my user, group or role occurs in one of the fields
     * 
     * @param viewName
     * @param fieldsToCheck
     * @return
     */
    public List<T> getAllMyObjects(String viewName, List<String> fieldsToCheck) {
        return getAllMyObjectsFrom(viewName, fieldsToCheck, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Loads all object where my user, group or role occurs in one of the fields
     * form the source database
     * 
     * @param viewName
     * @param fieldsToCheck
     * @param sourceDatabase
     * @return
     */
    public List<T> getAllMyObjectsFrom(String viewName, List<String> fieldsToCheck, Database sourceDatabase) {
        List<T> ret = new ArrayList<T>();
        List<String> lstRolesGroups = RoleAndGroupProvider.getInstance().getMyGroupsAndRoles();
        try {
            View viwDabases = sourceDatabase.getView(viewName);
            viwDabases.setAutoUpdate(false);
            Document docNext = viwDabases.getFirstDocument();
            while (docNext != null) {
                Document docCurrent = docNext;
                docNext = viwDabases.getNextDocument(docNext);
                if (isDocumentOfInterest(docCurrent, lstRolesGroups, fieldsToCheck)) {
                    convertDocument2ObjectAndAdd2List(ret, docCurrent);
                }
                docCurrent.recycle();

            }
            viwDabases.recycle();
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return ret;

    }

    /**
     * Loads all object where the user, group or role occurs in one of the
     * fields
     * 
     * @param userName
     *            Name of the user
     * @param viewName
     * @param fieldsToCheck
     * @return
     */
    public List<T> getAllObjectFor(String userName, String viewName, List<String> fieldsToCheck) {
        return getAllObjectsForFrom(userName, viewName, fieldsToCheck, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Loads all object where the user, group or role occurs in one of the
     * fields form the source database
     * 
     * @param userName
     * @param viewName
     * @param fieldsToCheck
     * @param sourceDatabase
     * @return
     */
    public List<T> getAllObjectsForFrom(String userName, String viewName, List<String> fieldsToCheck,
            Database sourceDatabase) {
        List<T> ret = new ArrayList<T>();
        List<String> lstRolesGroups = RoleAndGroupProvider.getInstance().getGroupsAndRolesOf(userName,
                sourceDatabase);
        try {
            View view = sourceDatabase.getView(viewName);
            view.setAutoUpdate(false);
            Document docNext = view.getFirstDocument();
            while (docNext != null) {
                Document docCurrent = docNext;
                docNext = view.getNextDocument(docNext);
                if (isDocumentOfInterest(docCurrent, lstRolesGroups, fieldsToCheck)) {
                    convertDocument2ObjectAndAdd2List(ret, docCurrent);
                }
                docCurrent.recycle();

            }
            view.recycle();
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return ret;

    }

    /**
     * Override this method with your implementation of the SoftDeleteProvider
     * 
     * @return
     */
    public ISoftDeletionProvider<T> getSoftDeletionProvider() {
        return null;
    }

    /**
     * Try's to softDelete the object from the current database. It throws a
     * DSSException, if no softdeleteprovider is defined.
     * 
     * @param objDelete
     * @return true if the operation was successful
     * @throws DSSException
     */
    public boolean softDelete(T objDelete) throws DSSException {
        return softDelete(objDelete, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Try's to softDelete the object from the current database. It throws a
     * DSSException, if no softdeleteprovider is defined.
     * 
     * @param objDelete
     * @param targetDatabase
     * @return true if the operation was successful
     * @throws DSSException
     */
    public boolean softDelete(T objDelete, Database targetDatabase) throws DSSException {

        ISoftDeletionProvider<T> sdProv = getSoftDeletionProvider();
        if (sdProv == null) {
            throw new DSSException("No softdeletion provider defined");
        }
        return sdProv.softDelete(objDelete, targetDatabase, this);
    }

    /**
     * Deletes an object from the current database. If direct is true, the
     * SoftDeleprovider is not used
     * 
     * @param objDelete
     * @param direct
     * @return
     * @throws DSSException
     */
    public boolean hardDelete(T objDelete, boolean direct) throws DSSException {
        return hardDelete(objDelete, ExtLibUtil.getCurrentDatabase(), direct);
    }

    /**
     * Deletes an object from the target database. If direct is true, the
     * SoftDeleprovider is not used
     * 
     * @param objDelete
     * @param targetDatabase
     * @param direct
     * @return
     * @throws DSSException
     */
    public boolean hardDelete(T objDelete, Database targetDatabase, boolean direct) throws DSSException {
        if (direct) {
            return DominoStorageService.getInstance().deleteObject(objDelete, targetDatabase);
        }
        ISoftDeletionProvider<T> sdProv = getSoftDeletionProvider();
        if (sdProv == null) {
            throw new DSSException("No softdeletion provider defined");
        }
        return sdProv.hardDelete(objDelete, targetDatabase, this);

    }

    /**
     * Undelet's an object from the current database using the
     * SoftDeleteProvider
     * 
     * @param objDelete
     * @return
     * @throws DSSException
     */
    public boolean undelete(T objDelete) throws DSSException {
        return undelete(objDelete, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Undelet's an object from the target database using the SoftDeleteProvider
     * 
     * @param objDelete
     * @param targetDatabase
     * @return
     * @throws DSSException
     */
    public boolean undelete(T objDelete, Database targetDatabase) throws DSSException {

        ISoftDeletionProvider<T> sdProv = getSoftDeletionProvider();
        if (sdProv == null) {
            throw new DSSException("No softdeletion provider defined");
        }
        return sdProv.undelete(objDelete, targetDatabase, this);
    }

    private boolean isDocumentOfInterest(Document docCurrent, List<String> lstRolesGroups,
            List<String> lstFieldsToCheck) {
        try {
            for (String strField : lstFieldsToCheck) {
                if (docCurrent.hasItem(strField)) {
                    List<String> lstValues = getStringListFromDocument(docCurrent, strField);
                    if (CollectionUtils.containsAny(lstRolesGroups, lstValues)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return false;
    }

    private List<String> getStringListFromDocument(Document docCurrent, String strField) {
        List<String> lstRC = new ArrayList<String>();
        try {
            Vector<?> vecRes = docCurrent.getItemValue(strField);
            for (Iterator<?> itValue = vecRes.iterator(); itValue.hasNext();) {
                lstRC.add("" + itValue.next());
            }
        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return lstRC;
    }

    /**
     * Override this function to create a blank object
     * 
     * @return
     */
    protected abstract T createObject();

    public List<ChangeLogEntry> getChangeLog(T objCurrent) {
        return getChangeLog(objCurrent, RoleAndGroupProvider.getInstance().getMyGroupsAndRoles());
    }

    /**
     * Get the ChangeLog entries for an object.
     * 
     * @param objCurrent
     * @param myRoles
     * @return
     */
    public List<ChangeLogEntry> getChangeLog(T objCurrent, List<String> myRoles) {
        List<ChangeLogEntry> lstRC = null;
        try {
            String strObjectClass = objCurrent.getClass().getCanonicalName();
            String strPK = DominoStorageService.getInstance().getObjectID(objCurrent).toString();
            lstRC = ChangeLogService.getInstance().getChangeLog(strObjectClass, strPK);
            for (Iterator<ChangeLogEntry> itCL = lstRC.iterator(); itCL.hasNext();) {
                ChangeLogEntry cl = itCL.next();
                if (!DominoStorageService.getInstance().isFieldAccessable(objCurrent, cl, myRoles)) {
                    itCL.remove();
                }

            }

        } catch (Exception e) {
            LoggerFactory.logError(getClass(), "General Error", e);
            throw new XPTRuntimeException("General Error", e);
        }
        return lstRC;
    }

    /**
     * Search for documents containing the search term in the current database,
     * using the fulltext search capability.
     * 
     * @param search
     * @return List with all objects of type T
     */
    public List<T> search(String search) {
        return searchFrom(search, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Search for documents containing the search term in the database db, using
     * the fulltext search capability.
     * 
     * @param search
     * @return List with all objects of type T
     */
    public List<T> searchFrom(String search, Database db) {
        List<T> result = new ArrayList<T>();
        try {
            DocumentCollection dclResult = db.FTSearch(search);
            if (dclResult.getCount() == 0) {
                dclResult.recycle();
                return result;
            }
            result = new ArrayList<T>(dclResult.getCount());
            Document docNext = dclResult.getFirstDocument();
            while (docNext != null) {
                Document docProcess = docNext;
                docNext = dclResult.getNextDocument();
                convertDocument2ObjectAndAdd2List(result, docProcess);
                docProcess.recycle();
            }
            dclResult.recycle();
        } catch (Exception e) {
            throw new XPTRuntimeException("Error during search of " + search, e);
        }
        return result;
    }

    /**
     * Search for documents containing the search term in the view of the
     * current database, using the fulltext search capability.
     * 
     * @param search
     * @param viewName
     * @return
     */
    public List<T> searchInView(String search, String viewName) {
        return searchInViewFrom(search, viewName, ExtLibUtil.getCurrentDatabase());
    }

    /**
     * Search for documents containing the search term in the view of the
     * database db, using the fulltext search capability.
     * 
     * @param search
     * @param viewName
     * @param db
     * @return
     */
    public List<T> searchInViewFrom(String search, String viewName, Database db) {
        List<T> result = new ArrayList<T>();
        try {
            View view = db.getView(viewName);
            int count = view.FTSearch(search);
            if (count == 0) {
                view.recycle();
                return result;
            }
            result = new ArrayList<T>(count);
            Document docNext = view.getFirstDocument();
            while (docNext != null) {
                Document docProcess = docNext;
                docNext = view.getNextDocument(docNext);
                convertDocument2ObjectAndAdd2List(result, docProcess);
                docProcess.recycle();
            }
            view.recycle();
        } catch (Exception e) {
            throw new XPTRuntimeException("Error during search of " + search + " in view " + viewName, e);
        }
        return result;
    }

    private void convertDocument2ObjectAndAdd2List(List<T> result, Document docProcess) throws DSSException {
        T obj = createObject();
        if (DominoStorageService.getInstance().getObjectWithDocument(obj, docProcess)) {
            result.add(obj);
        }
    }
}