org.archiviststoolkit.mydomain.DomainAccessObjectImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.archiviststoolkit.mydomain.DomainAccessObjectImpl.java

Source

/**
 * Archivists' Toolkit(TM) Copyright  2005-2007 Regents of the University of California, New York University, & Five Colleges, Inc.
 * All rights reserved.
 *
 * This software is free. You can redistribute it and / or modify it under the terms of the Educational Community License (ECL)
 * version 1.0 (http://www.opensource.org/licenses/ecl1.php)
 *
 * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ECL license for more details about permissions and limitations.
 *
 *
 * Archivists' Toolkit(TM)
 * http://www.archiviststoolkit.org
 * info@archiviststoolkit.org
 */

package org.archiviststoolkit.mydomain;

//==============================================================================
// Import Declarations
//==============================================================================

import com.jgoodies.validation.ValidationResult;
import org.apache.commons.beanutils.BeanUtils;
import org.archiviststoolkit.ApplicationFrame;
import org.archiviststoolkit.dialog.ErrorDialog;
import org.archiviststoolkit.dialog.QueryEditor;
import org.archiviststoolkit.exceptions.DeleteException;
import org.archiviststoolkit.exceptions.MergeException;
import org.archiviststoolkit.exceptions.ValidationException;
import org.archiviststoolkit.hibernate.ATSearchCriterion;
import org.archiviststoolkit.hibernate.AuditInterceptor;
import org.archiviststoolkit.hibernate.SessionFactory;
import org.archiviststoolkit.model.*;
import org.archiviststoolkit.model.validators.ATValidator;
import org.archiviststoolkit.model.validators.ValidatorFactory;
import org.archiviststoolkit.structure.DatabaseTables;
import org.archiviststoolkit.swing.InfiniteProgressPanel;
import org.archiviststoolkit.util.NameUtils;
import org.archiviststoolkit.util.StringHelper;
import org.hibernate.*;
import org.hibernate.criterion.*;

import javax.swing.*;
import java.awt.*;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.*;
import java.util.List;
import java.util.logging.Logger;

/**
 * Default implementation of a DomainAccessObject specific to
 * hibernate version 2.
 */

public class DomainAccessObjectImpl implements DomainAccessObject, DomainAccessListener {

    private boolean debug = false;

    /**
     * Class logger.
     */

    private static Logger logger = Logger.getLogger(DomainAccessObjectImpl.class.getPackage().getName());

    /**
     * Class which this DOA implementation refers to.
     */
    private Class persistentClass = null;

    /**
     * listeners who are interested in this class changing.
     * TODO: need to change this to a collection type not vector
     */
    private Vector<DomainAccessListener> listeners = new Vector<DomainAccessListener>();

    private static Session longSession = null; // This needs to be static to prevent those can't save messages as in ART-1680

    private String humanReadableSearchString = "";

    /**
     * Constructor which builds a DAO for this class.
     *
     * @param clazz the class to build to
     */

    public DomainAccessObjectImpl(final Class clazz) {
        this.persistentClass = clazz;
    }

    /**
     * Add a listener for this DAO.
     *
     * @param listener the listener to add
     */

    public final void addListener(final DomainAccessListener listener) {
        listeners.add(listener);
    }

    /**
     * Remove a listener from this DAO.
     *
     * @param listener the listener to remove
     */

    public final void removeListener(final DomainAccessListener listener) {
        listeners.remove(listener);
    }

    /**
     * Notify all the listeners of an event.
     *
     * @param event the event which should be sent to all listeners
     */

    public final void notifyListeners(final DomainAccessEvent event) {

        for (Object listener1 : listeners) {
            DomainAccessListener listener = (DomainAccessListener) listener1;
            listener.domainChanged(event);
        }
    }

    /**
     * Add an instance to this DAO.
     *
     * @param domainObject the object to add
     * @throws PersistenceException fails if we cannot persist the instance
     */

    public final void add(final DomainObject domainObject) throws PersistenceException {
        Session session = SessionFactory.getInstance()
                .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
        Transaction tx = null;
        try {

            updateClassSpecific(domainObject, session);
            tx = session.beginTransaction();
            session.saveOrUpdate(domainObject);
            tx.commit();
            //         session.flush();
            //         session.connection().commit();

        } catch (HibernateException hibernateException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException("failed to add, class: " + this.getClass() + " object: " + domainObject,
                    hibernateException);
        } catch (Exception sqlException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException("failed to add, class: " + this.getClass() + " object: " + domainObject,
                    sqlException);
        } finally {
            session.close();
        }

        //      SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.INSERT, domainObject));
    }

    /**
     * Add a group of instances.
     *
     * @param collection the objects to add
     * @throws PersistenceException fails if we cannot persist the instance
     */

    public final void addGroup(final Collection collection, Component parent) throws PersistenceException {
        Session session = SessionFactory.getInstance()
                .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
        DomainObject domainObject = null;
        try {
            Iterator iterator = collection.iterator();
            int numberOfRecords = collection.size();

            ProgressMonitor monitor = new ProgressMonitor(parent, "Saving Records", null, 0, numberOfRecords);
            int count = 0;

            while (iterator.hasNext()) {
                domainObject = (DomainObject) iterator.next();
                updateClassSpecific(domainObject, session);
                session.saveOrUpdate(domainObject);
                monitor.setProgress(count++);
            }
            monitor.close();
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new PersistenceException("failed to add, class: " + this.getClass() + " object: " + domainObject,
                    hibernateException);
        } catch (Exception sqlException) {
            throw new PersistenceException("failed to add, class: " + this.getClass() + " object: " + domainObject,
                    sqlException);
        }

        //      HibernateUtil.closeSession();
        SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.INSERTGROUP, collection));
    }

    /**
     * Update the instance within this DAO.
     *
     * @param domainObject the instance to update
     * @throws PersistenceException fails if we cannot update the instance
     */

    public final void update(final DomainObject domainObject) throws PersistenceException {
        Session session = SessionFactory.getInstance()
                .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
        Transaction tx = null;

        try {
            updateClassSpecific(domainObject, session);
            tx = session.beginTransaction();
            session.saveOrUpdate(domainObject);
            tx.commit();
            //         session.flush();
            //         session.connection().commit();
        } catch (HibernateException hibernateException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, hibernateException);
        } catch (Exception sqlException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, sqlException);
        } finally {
            session.close();
        }

        //      SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.UPDATE, domainObject));
    }

    /**
     * Method to update a domain object with that excepts a session
     *
     * @param domainObject
     * @param session
     * @throws PersistenceException
     */
    public final void update(final DomainObject domainObject, Session session) throws PersistenceException {
        Transaction tx = null;

        try {
            updateClassSpecific(domainObject, session);
            tx = session.beginTransaction();
            session.saveOrUpdate(domainObject);
            tx.commit();
        } catch (HibernateException hibernateException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, hibernateException);
        } catch (Exception sqlException) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, sqlException);
        }

        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.UPDATE, domainObject));
    }

    /**
     * Update the instance within this DAO.
     *
     * @param domainObject the instance to update
     * @throws PersistenceException fails if we cannot update the instance
     */

    public final void updateLongSession(final DomainObject domainObject) throws PersistenceException {
        updateLongSession(domainObject, true);
    }

    /**
     * Update the instance within this DAO.
     *
     * @param domainObject the instance to update
     * @throws PersistenceException fails if we cannot update the instance
     */

    public final void updateLongSession(final DomainObject domainObject, boolean closeSession)
            throws PersistenceException {

        try {
            updateClassSpecific(domainObject, longSession);
            longSession.saveOrUpdate(domainObject);
            longSession.flush();
            longSession.connection().commit();
        } catch (HibernateException hibernateException) {
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, hibernateException);
        } catch (Exception sqlException) {
            throw new PersistenceException(
                    "failed to update, class: " + this.getClass() + " object: " + domainObject, sqlException);
        }

        if (closeSession) {
            SessionFactory.getInstance().closeSession(longSession);
        }
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.UPDATE, domainObject));
    }

    /**
     * Delete these objects from the data store.
     *
     * @param collection the object to delete
     * @throws PersistenceException fails if we cannot delete the instance
     */

    public void deleteGroup(final Collection collection) throws PersistenceException {

        Session session = SessionFactory.getInstance().openSession();
        DomainObject domainObject = null;
        try {

            for (Object aCollection : collection) {
                domainObject = (DomainObject) aCollection;
                domainObject.testDeleteRules();
                domainObject = (DomainObject) session.load(getPersistentClass(), domainObject.getIdentifier());
                session.delete(domainObject);
            }

            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + hibernateException);
            throw new PersistenceException("failed to delete", hibernateException);
        } catch (ClassCastException classCastException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + classCastException);
            throw new PersistenceException("failed to delete", classCastException);
        } catch (SQLException sqlException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + sqlException);
            throw new PersistenceException("failed to delete", sqlException);
        } catch (DeleteException e) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + e);
            throw new PersistenceException("failed to delete", e);
        }
        SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.REMOVEGROUP, collection));
    }

    /**
     * Delete this object from the data store.
     *
     * @param domainObject the object to delete
     * @throws DeleteException fails if we cannot delete the instance
     */

    public void delete(final DomainObject domainObject) throws DeleteException {

        Session session = SessionFactory.getInstance().openSession();
        try {
            domainObject.testDeleteRules();
            session.delete(domainObject);
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + hibernateException);
            throw new DeleteException("failed to delete", hibernateException);
        } catch (ClassCastException classCastException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + classCastException);
            throw new DeleteException("failed to delete", classCastException);
        } catch (SQLException sqlException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + sqlException);
            throw new DeleteException("failed to findbyprimarykey", sqlException);
        } catch (PersistenceException e) {
            new ErrorDialog("", StringHelper.getStackTrace(e)).showDialog();
        }
        SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.REMOVE, domainObject));
    }

    public final void deleteLongSession(final DomainObject domainObject) throws DeleteException {
        deleteLongSession(domainObject, true);
    }

    public final void deleteLongSession(final DomainObject domainObject, boolean closeSession)
            throws DeleteException {

        try {
            domainObject.testDeleteRules();
            longSession.delete(domainObject);
            longSession.flush();
            longSession.connection().commit();

        } catch (HibernateException hibernateException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + hibernateException);
            throw new DeleteException("failed to delete", hibernateException);
        } catch (ClassCastException classCastException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + classCastException);
            throw new DeleteException("failed to delete", classCastException);
        } catch (SQLException sqlException) {
            logger.severe("Failed to Delete instance " + domainObject + " because " + sqlException);
            throw new DeleteException("failed to findbyprimarykey", sqlException);
        } catch (PersistenceException e) {
            new ErrorDialog("", StringHelper.getStackTrace(e)).showDialog();
        }
        if (closeSession) {
            SessionFactory.getInstance().closeSession(longSession);
        }
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.REMOVE, domainObject));
    }

    /**
     * Delete this object from the data store.
     *
     * @param identifier the id of the object to delete
     * @throws DeleteException fails if we cannot delete the instance
     */

    public final void deleteById(final Long identifier) throws DeleteException {

        Session session = SessionFactory.getInstance().openSession();
        DomainObject domainObject = null;
        try {
            domainObject = findByPrimaryKeyCommon(identifier, session);
            domainObject.testDeleteRules();
            session.delete(domainObject);
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new DeleteException("failed to delete", hibernateException);
        } catch (ClassCastException classCastException) {
            throw new DeleteException("failed to delete", classCastException);
        } catch (SQLException sqlException) {
            throw new DeleteException("failed to findbyprimarykey", sqlException);
        } catch (PersistenceException e) {
            throw new DeleteException("failed to delete", e);
        } catch (LookupException e) {
            throw new DeleteException("failed to delete", e);
        }
        SessionFactory.getInstance().closeSession(session);
        this.notifyListeners(new DomainAccessEvent(DomainAccessEvent.REMOVE, domainObject));
    }

    /**
     * Find an instance by its identifier.
     *
     * @param identifier the identifier we are looking for
     * @return the domain object with the required identifier
     * @throws LookupException fails if we cannot execute the lookup
     */

    public DomainObject findByPrimaryKeyCommon(final Long identifier, Session session) throws LookupException {

        DomainObject domainObject;

        try {

            //         try {
            if (getPersistentClass() == Names.class) {
                Criteria criteria = session.createCriteria(Names.class);
                criteria.setFetchMode("contactNotes", FetchMode.JOIN);
                criteria.setFetchMode("nonPreferredNames", FetchMode.JOIN);
                criteria.setFetchMode("archDescriptionNames", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == Accessions.class) {
                Criteria criteria = session.createCriteria(Accessions.class);
                criteria.setFetchMode("names", FetchMode.JOIN);
                criteria.setFetchMode("repeatingData", FetchMode.JOIN);
                criteria.setFetchMode("resources", FetchMode.JOIN);
                criteria.setFetchMode("subjects", FetchMode.JOIN);
                criteria.setFetchMode("locations", FetchMode.JOIN);
                criteria.setFetchMode("deaccessions", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == Subjects.class) {
                Criteria criteria = session.createCriteria(Subjects.class);
                criteria.setFetchMode("archDescriptionSubjects", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == Resources.class) {
                Criteria criteria = session.createCriteria(Resources.class);
                criteria.setFetchMode("names", FetchMode.JOIN);
                criteria.setFetchMode("accessions", FetchMode.JOIN);
                criteria.setFetchMode("subjects", FetchMode.JOIN);
                //               criteria.setFetchMode("repeatingData", FetchMode.JOIN);
                //               criteria.setFetchMode("instances", FetchMode.JOIN);
                //               criteria.setFetchMode("resourcesComponents", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == ResourcesComponents.class) {
                Criteria criteria = session.createCriteria(ResourcesComponents.class);
                criteria.setFetchMode("names", FetchMode.JOIN);
                criteria.setFetchMode("instances", FetchMode.JOIN);
                criteria.setFetchMode("subjects", FetchMode.JOIN);
                criteria.setFetchMode("repeatingData", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == Locations.class) {
                Criteria criteria = session.createCriteria(Locations.class);
                criteria.setFetchMode("repository", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else if (getPersistentClass() == DigitalObjects.class) {
                Criteria criteria = session.createCriteria(DigitalObjects.class);
                //               criteria.setFetchMode("names", FetchMode.JOIN);
                //               criteria.setFetchMode("repeatingData", FetchMode.JOIN);
                //               criteria.setFetchMode("subjects", FetchMode.JOIN);
                //               criteria.setFetchMode("fileVersions", FetchMode.JOIN);
                criteria.add(Restrictions.idEq(identifier));
                domainObject = (DomainObject) criteria.uniqueResult();

            } else {
                domainObject = (DomainObject) session.load(getPersistentClass(), identifier);
            }

            //         } catch (ObjectNotFoundException objectNotFoundException) {
            //            new ErrorDialog("", StringHelper.getStackTrace(e)).showDialog();
            //            domainObject = null;
            //            logger.log(Level.INFO, "Object could not be found by key " + identifier);
            //         }

            session.flush();
            session.connection().commit();

        } catch (ObjectNotFoundException objectNotFoundException) {
            throw new LookupException("failed to findbyprimarykey: " + objectNotFoundException.toString(),
                    objectNotFoundException);
        } catch (HibernateException hibernateException) {
            throw new LookupException("failed to findbyprimarykey: " + hibernateException.toString(),
                    hibernateException);
        } catch (SQLException sqlException) {
            throw new LookupException("failed to findbyprimarykey: " + sqlException.toString(), sqlException);
        }

        return (domainObject);
    }

    /**
     * Find an instance by its identifier.
     *
     * @param identifier the identifier we are looking for
     * @return the domain object with the required identifier
     * @throws LookupException fails if we cannot execute the lookup
     */

    public final DomainObject findByPrimaryKey(final Long identifier) throws LookupException {

        Session session = SessionFactory.getInstance().openSession();
        DomainObject domainObject = findByPrimaryKeyCommon(identifier, session);
        SessionFactory.getInstance().closeSession(session);
        return domainObject;
    }

    /**
     * Find an instance by its identifier.
     *
     * @param identifier the identifier we are looking for
     * @return the domain object with the required identifier
     * @throws LookupException fails if we cannot execute the lookup
     */

    public final DomainObject findByPrimaryKeyLongSession(final Long identifier) throws LookupException {

        openLongSession();
        DomainObject domainObject = findByPrimaryKeyCommon(identifier, longSession);
        //      SessionFactory.getInstance().disconnectSession(longSession);
        return domainObject;
    }

    private void openLongSession() {
        if (longSession == null || !longSession.isOpen()) {
            longSession = SessionFactory.getInstance()
                    .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
            if (debug) {
                System.out.println("open session");
            }
        }
    }

    /**
     * Find an instance by its identifier.
     *
     * @param identifier the identifier we are looking for
     * @return the domain object with the required identifier
     * @throws LookupException fails if we cannot execute the lookup
     */

    public final DomainObject findByPrimaryKeyLongSessionForPrinting(final Long identifier) throws LookupException {

        openLongSession();
        DomainObject domainObject = (DomainObject) longSession.load(getPersistentClass(), identifier);
        //      SessionFactory.getInstance().disconnectSession(longSession);
        return domainObject;
    }

    public void closeLongSession() throws SQLException {
        longSession.flush();
        longSession.connection().commit();
        SessionFactory.getInstance().closeSession(longSession);
    }

    public void closeLongSessionRollback() throws SQLException {
        if (longSession.isOpen()) { // check to see of the long session is open before trying to close it
            longSession.connection().rollback();
            SessionFactory.getInstance().closeSession(longSession);
        }
    }

    public Session getLongSession() {
        openLongSession();
        return longSession;
    }

    /**
     * Return a collection with everything in this DAO.
     *
     * @return a collection of everything of this class
     * @throws LookupException fails if we cannot execute the lookup
     */

    //   public Collection findAll() throws LookupException {
    //      return (findAll(null));
    //   }

    /**
     * Return a collection with everything in this DAO.
     *
     * @return a collection of everything of this class
     * @throws LookupException fails if we cannot execute the lookup
     */

    public Collection findAll(String... sortFields) throws LookupException {
        return findAll(null, sortFields);
    }

    public Collection findAll(LockMode lockmode, String... sortFields) throws LookupException {
        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        List completeList = (List) findAllCommon(session, lockmode, sortFields);
        //      SessionFactory.getInstance().closeSession(session);
        return completeList;
    }

    public Collection findAllLongSession(String... sortFields) throws LookupException {
        longSession = SessionFactory.getInstance().openSession(
                new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()), getPersistentClass());
        return findAllCommon(longSession, sortFields);

    }

    public Collection findAllLongSession(Boolean alwaysApplyFilters, String... sortFields) throws LookupException {
        longSession = SessionFactory.getInstance().openSession(
                new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()), getPersistentClass(),
                alwaysApplyFilters);
        return findAllCommon(longSession, sortFields);

    }

    private Collection findAllCommon(Session session, String... sortFields) throws LookupException {
        return findAllCommon(session, null, sortFields);
    }

    private Collection findAllCommon(Session session, LockMode lockmode, String... sortFields)
            throws LookupException {
        List completeList;
        Transaction tx = null;
        try {
            session.setFlushMode(FlushMode.MANUAL);

            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(getPersistentClass());
            for (String field : sortFields) {
                criteria.addOrder(Order.asc(field));
            }
            //         System.out.println("Find all: " + persistentClass.getName());
            //         if (lockmode != null) {
            //            criteria.setLockMode(lockmode);
            //            System.out.println("Setting lock mode: " + lockmode);
            //         }
            completeList = criteria.list();
            //         if (lockmode != null && lockmode == LockMode.READ) {
            //            System.out.println("Rollback because read only");
            //            session.connection().rollback();
            //         } else {
            //            session.flush();
            //            session.connection().commit();
            //         }
            //         session.flush();
            //         session.connection().commit();
            tx.commit();

        } catch (RuntimeException ex) {
            try {
                tx.rollback();
            } catch (HibernateException e) {
                //todo log error
            }
            throw new LookupException("failed to find all", ex);
        } finally {
            if (session != longSession) {
                session.close();
            }
        }

        return (completeList);
    }

    /**
     * Find a collection of domain objects by direct hql query.
     *
     * @param queryString the hql statement
     * @return the collection of domain objects
     * @throws LookupException if we failed to find the objects.
     */
    public final Collection findByQuery(final String queryString) throws LookupException {
        List list;

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        try {
            Query query = session.createQuery(queryString);

            list = query.list();
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new LookupException("failed to findbynamedquery 1 ", hibernateException);
        } catch (SQLException sqlException) {
            throw new LookupException("failed to findbynamedquery 2", sqlException);
        }

        SessionFactory.getInstance().closeSession(session);

        return (list);

    }

    /**
     * Method to search by query editory using long session
     *
     * @param editor        The quesry editor
     * @param progressPanel The progress panel
     * @return The result that were found or an empty string
     */
    public final Collection findByQueryEditorLongSession(QueryEditor editor, InfiniteProgressPanel progressPanel) {

        Criteria criteria = processQueryEditorCriteria(getLongSession(), editor.getClazz(), editor);
        return criteria.list();
    }

    /**
     * Find a collection of domain objects by direct hql query.
     *
     * @param editor an AT query editor
     * @return the collection of domain objects
     */
    public final Collection findByQueryEditor(final QueryEditor editor, InfiniteProgressPanel progressPanel) {

        boolean includeComponents = false;
        if (persistentClass == Resources.class && editor.getIncludeComponents()) {
            includeComponents = true;
        }
        if (editor.getAlternateQuery()) {
            return findByQueryEditorAlt(editor, progressPanel);

        } else if (!includeComponents) {
            Session session = SessionFactory.getInstance().openSession(null, getPersistentClass(), true);
            Criteria criteria = processQueryEditorCriteria(session, editor.getClazz(), editor);

            // if searching digital object then need to see if to only search for parent digital objects
            if (persistentClass == DigitalObjects.class && !editor.getIncludeComponents()) {
                criteria.add(Restrictions.isNull("parent"));
            }

            Collection collection = criteria.list();
            SessionFactory.getInstance().closeSession(session);
            return collection;

        } else {
            Collection<ResourcesComponentsSearchResult> resourcesAndComponetsResults = new ArrayList<ResourcesComponentsSearchResult>();
            HashMap<DomainObject, String> contextMap = new HashMap<DomainObject, String>();
            HashMap<ResourcesComponents, Resources> componentParentResourceMap = new HashMap<ResourcesComponents, Resources>();

            Session session = SessionFactory.getInstance().openSession(null, getPersistentClass(), true);

            ATSearchCriterion comparison1 = editor.getCriterion1();
            ATSearchCriterion comparison2 = editor.getCriterion2();

            Criteria criteria = session.createCriteria(editor.getClazz());
            criteria.add(comparison1.getCiterion());
            Collection collection = criteria.list();

            if (comparison2.getCiterion() == null) {
                addContextInfo(contextMap, collection, comparison1.getContext());
                addResourcesCommonToComponetResultSet(collection, resourcesAndComponetsResults, contextMap);
                humanReadableSearchString = comparison1.getSearchString();
            } else {
                // we have a boolean search
                Set returnCollection = new HashSet(collection);
                criteria = session.createCriteria(editor.getClazz());
                criteria.add(comparison2.getCiterion());
                Collection collection2 = criteria.list();
                if (editor.getChosenBoolean1().equalsIgnoreCase("and")) {
                    returnCollection.retainAll(collection2);
                    humanReadableSearchString = comparison1.getSearchString() + " and "
                            + comparison2.getSearchString();
                } else {
                    returnCollection.addAll(collection2);
                    humanReadableSearchString = comparison1.getSearchString() + " or "
                            + comparison2.getSearchString();
                }
                addContextInfo(contextMap, collection, comparison1.getContext());
                addContextInfo(contextMap, collection2, comparison2.getContext());
                addResourcesCommonToComponetResultSet(returnCollection, resourcesAndComponetsResults, contextMap);

            }
            SessionFactory.getInstance().closeSession(session);

            Resources resource;
            //         addResourcesCommonToComponetResultSet(collection, resourcesAndComponetsResults, null);

            ResourcesDAO resourceDao = new ResourcesDAO();
            progressPanel.setTextLine("Searching for components that match the criteria", 2);

            session = SessionFactory.getInstance().openSession(ResourcesComponents.class);
            criteria = session.createCriteria(ResourcesComponents.class);
            criteria.add(comparison1.getCiterion());
            Collection components = criteria.list();
            addContextInfo(contextMap, components, comparison1.getContext());
            ResourcesComponents component;
            if (comparison2.getCiterion() == null) {
                int numberOfComponents = components.size();
                int count = 1;
                for (Object object : components) {
                    component = (ResourcesComponents) object;
                    progressPanel.setTextLine(
                            "Gathering resources by component matches " + count++ + " of " + numberOfComponents, 2);
                    resource = resourceDao.findResourceByComponent(component);
                    if (doesUserHaveAccessRightsToResource(resource)) {
                        resourcesAndComponetsResults.add(
                                new ResourcesComponentsSearchResult(resource, component, comparison1.getContext()));
                    }
                }
                SessionFactory.getInstance().closeSession(session);
                return resourcesAndComponetsResults;

            } else {

                criteria = session.createCriteria(ResourcesComponents.class);
                criteria.add(comparison2.getCiterion());
                Collection components2 = criteria.list();
                addContextInfo(contextMap, components2, comparison2.getContext());

                Set returnCollection = new HashSet(components);
                if (editor.getChosenBoolean1().equalsIgnoreCase("and")) {
                    returnCollection.retainAll(components2);
                } else {
                    returnCollection.addAll(components2);
                }
                //find the parents for all the components
                for (Object object : returnCollection) {
                    int numberOfComponents = components.size();
                    int count = 1;
                    component = (ResourcesComponents) object;
                    progressPanel.setTextLine(
                            "Gathering resources by component matches " + count++ + " of " + numberOfComponents, 2);
                    resource = resourceDao.findResourceByComponent(component);
                    componentParentResourceMap.put(component, resource);
                }
                addResourcesCommonToComponetResultSet(returnCollection, resourcesAndComponetsResults, contextMap,
                        componentParentResourceMap);
                return resourcesAndComponetsResults;
            }

            //         criteria = processQueryEditorCriteria(session, ResourcesComponents.class, editor);
            ////         Collection components = criteria.list();
            ////         ResourcesComponents component;
            //         int numberOfComponents = components.size();
            //         int count = 1;
            //         for (Object object : components) {
            //            component = (ResourcesComponents) object;
            //            progressPanel.setTextLine("Gathering resources by component matches " + count++ + " of " + numberOfComponents, 2);
            //            resource = resourceDao.findResourceByComponent(component);
            //            resourcesAndComponetsResults.add(new ResourcesComponentsSearchResult(resource, component, "dummy string"));
            //         }
            //         SessionFactory.getInstance().closeSession(session);
            //         return resourcesAndComponetsResults;

        }
    }

    private void addResourcesCommonToComponetResultSet(Collection collection,
            Collection<ResourcesComponentsSearchResult> resourcesAndComponetsResults,
            HashMap<DomainObject, String> contextMap) {
        addResourcesCommonToComponetResultSet(collection, resourcesAndComponetsResults, contextMap, null);
    }

    private void addResourcesCommonToComponetResultSet(Collection collection,
            Collection<ResourcesComponentsSearchResult> resourcesAndComponetsResults,
            HashMap<DomainObject, String> contextMap,
            HashMap<ResourcesComponents, Resources> componentParentResourceMap) {
        Resources resource;
        ResourcesComponents component;
        for (Object o : collection) {
            if (o instanceof Resources) {
                resource = (Resources) o;
                if (doesUserHaveAccessRightsToResource(resource)) {
                    resourcesAndComponetsResults
                            .add(new ResourcesComponentsSearchResult(resource, contextMap.get(resource)));
                }
            } else if (o instanceof ResourcesComponents && componentParentResourceMap != null) {
                component = (ResourcesComponents) o;
                resource = componentParentResourceMap.get(component);
                if (resource != null && doesUserHaveAccessRightsToResource(resource)) {
                    resourcesAndComponetsResults.add(
                            new ResourcesComponentsSearchResult(resource, component, contextMap.get(component)));
                }
            }
        }
    }

    /**
     * Method to check to see if the user has the rights to access the resource that
     * was return from a search based on if they have the right to access records from the
     * repository of the return resource record
     *
     * @param resource The resource to check
     * @return true if the user can access the resource, false if they can't
     */
    private boolean doesUserHaveAccessRightsToResource(Resources resource) {
        if (ApplicationFrame.getInstance().getCurrentUser() != null
                && !Users.doesCurrentUserHaveAccess(Users.ACCESS_CLASS_SUPERUSER)) {

            if (ApplicationFrame.getInstance().getCurrentUser().getRepository().equals(resource.getRepository())) {
                return true;
            } else {
                return false;
            }
        }

        return true; // just return true to allow user to access the resource
    }

    private Criteria processQueryEditorCriteria(Session session, Class clazz, QueryEditor editor) {
        Criteria criteria = session.createCriteria(clazz);
        ATSearchCriterion comparison1 = editor.getCriterion1();
        ATSearchCriterion comparison2 = editor.getCriterion2();
        if (comparison2.getCiterion() == null) {
            criteria.add(comparison1.getCiterion());
            humanReadableSearchString = comparison1.getSearchString();
        } else {
            if (editor.getChosenBoolean1().equalsIgnoreCase("and")) {
                criteria.add(comparison1.getCiterion());
                criteria.add(comparison2.getCiterion());
                humanReadableSearchString = comparison1.getSearchString() + " <font color='red'>and</font> "
                        + comparison2.getSearchString();
            } else {
                criteria.add(Expression.or(comparison1.getCiterion(), comparison2.getCiterion()));
                humanReadableSearchString = comparison1.getSearchString() + " <font color='red'>or</font> "
                        + comparison2.getSearchString();
            }
        }
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return criteria;
    }

    //todo this method is a mess. There must be an easier way.
    private Collection findByQueryEditorAlt(QueryEditor editor, InfiniteProgressPanel progressPanel) {
        Session session;
        Criteria criteria;
        Set returnCollection = new HashSet();
        Set subsequentCollections = null;
        Set returnComponentCollection = new HashSet();
        Set subsequentComponentCollections = null;
        HashMap<ResourcesComponents, Resources> componentParentResourceMap = new HashMap<ResourcesComponents, Resources>();
        HashMap<DomainObject, String> contextMap = new HashMap<DomainObject, String>();
        boolean includeComponents = false;
        ArrayList<ResourcesComponentsSearchResult> resourcesAndComponetsResults = new ArrayList<ResourcesComponentsSearchResult>();
        ResourcesComponents component;

        //this is a loop of set intersections. In the first pass create a set
        //in all subsequent passes create a new set and perform an intersection on the
        //two sets. Java does this with the set.retainAll() method.
        if (persistentClass == Accessions.class || persistentClass == Resources.class
                || persistentClass == DigitalObjects.class) {
            //if we are including components then initialize the return set
            if (persistentClass == Resources.class && editor.getIncludeComponentsRelatedSearch()) {
                includeComponents = true;
            }
            boolean firstPass = true;
            subsequentCollections = new HashSet();
            humanReadableSearchString = "";
            for (QueryEditor.CriteriaRelationshipPairs criteriaPair : editor.getAltFormCriteria()) {
                session = SessionFactory.getInstance().openSession(null, getPersistentClass(), true);
                criteria = processCriteria(session, editor.getClazz(), criteriaPair);

                // if searching digital objects then need to see if to only search for parent digital objects
                if (persistentClass == DigitalObjects.class && !editor.getIncludeComponents()) {
                    criteria.add(Restrictions.isNull("parent"));
                }

                if (firstPass) {
                    returnCollection = new HashSet(criteria.list());
                } else {
                    subsequentCollections = new HashSet(criteria.list());
                }
                if (includeComponents) {
                    addContextInfo(contextMap, criteria.list(), criteriaPair.getContext());
                }
                SessionFactory.getInstance().closeSession(session);

                if (persistentClass == Resources.class && !criteriaPair.getResourceOnly() && includeComponents) {
                    subsequentComponentCollections = new HashSet();
                    session = SessionFactory.getInstance().openSession(ResourcesComponents.class);
                    criteria = processCriteria(session, ResourcesComponents.class, criteriaPair, false);
                    ResourcesDAO resourceDao = new ResourcesDAO();
                    Resources resource;
                    progressPanel.setTextLine("Searching for components that match the criteria", 2);
                    Collection components = criteria.list();
                    int numberOfComponents = components.size();
                    int count = 1;
                    for (Object object : components) {
                        progressPanel.setTextLine(
                                "Gathering resources by component matches " + count++ + " of " + numberOfComponents,
                                2);
                        component = (ResourcesComponents) object;
                        resource = resourceDao.findResourceByComponent(component);
                        componentParentResourceMap.put(component, resource);
                        addContextInfo(contextMap, component, criteriaPair.getContext());
                        if (firstPass) {
                            //if you are including components then add the component to the result set
                            //otherwise add the parent resource
                            if (includeComponents) {
                                returnComponentCollection.add(component);
                            } else {
                                returnCollection.add(resource);
                            }
                        } else {
                            //if you are including components then add the component to the result set
                            //otherwise add the parent resource
                            if (includeComponents) {
                                subsequentComponentCollections.add(object);
                            } else {
                                subsequentCollections.add(resource);
                            }
                        }
                    }
                    SessionFactory.getInstance().closeSession(session);
                }
                if (firstPass) {
                    firstPass = false;
                } else {
                    returnCollection.retainAll(subsequentCollections);
                    if (includeComponents) {
                        returnComponentCollection.retainAll(subsequentComponentCollections);
                    }
                }
            }
        }
        progressPanel.close();
        if (includeComponents) {
            addResourcesCommonToComponetResultSet(returnCollection, resourcesAndComponetsResults, contextMap);
            addResourcesCommonToComponetResultSet(returnComponentCollection, resourcesAndComponetsResults,
                    contextMap, componentParentResourceMap);
            return resourcesAndComponetsResults;
        } else {
            return returnCollection;
        }
    }

    private void addContextInfo(HashMap<DomainObject, String> contextMap, Collection resultSet, String context) {
        for (Object o : resultSet) {
            addContextInfo(contextMap, (DomainObject) o, context);
        }
    }

    private void addContextInfo(HashMap<DomainObject, String> contextMap, DomainObject domainObject,
            String context) {
        if (contextMap.containsKey(domainObject)) {
            contextMap.put(domainObject, contextMap.get(domainObject) + ", " + context);
        } else {
            contextMap.put(domainObject, context);
        }
    }

    private Criteria processCriteria(Session session, Class clazz,
            QueryEditor.CriteriaRelationshipPairs criteriaPair) {
        return processCriteria(session, clazz, criteriaPair, true);
    }

    private Criteria processCriteria(Session session, Class clazz,
            QueryEditor.CriteriaRelationshipPairs criteriaPair, boolean appendToHumanReadableSearchScreen) {
        Criteria criteria;
        Conjunction junction;
        Criteria addedCriteria;
        criteria = session.createCriteria(clazz);

        if (appendToHumanReadableSearchScreen) {
            humanReadableSearchString = StringHelper.concat(" <font color='red'>and</font> ",
                    humanReadableSearchString, criteriaPair.getHumanReadableSearchString());
        }
        junction = Restrictions.conjunction();
        if (criteriaPair.getSecondPropertyName() == null) {
            addedCriteria = criteria.createCriteria(criteriaPair.getPropertyName());
        } else {
            addedCriteria = criteria.createCriteria(criteriaPair.getPropertyName())
                    .createCriteria(criteriaPair.getSecondPropertyName());
        }
        for (Criterion criterion : criteriaPair.getCriteriaList()) {
            junction.add(criterion);
        }
        addedCriteria.add(junction);
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return criteria;
    }

    /**
     * Find a collection of domain objects by example.
     *
     * @param instance the example object
     * @return the collection of domain objects
     * @throws LookupException if we failed to find the objects.
     */
    public final Collection findByExample(final Object instance) throws LookupException {
        List results;

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        try {
            Example example = Example.create(instance).excludeZeroes() //exclude zero valued properties
                    .ignoreCase() //perform case insensitive string comparisons
                    .excludeProperty("version").excludeProperty("modifieddate").excludeProperty("creationdate")
                    .excludeProperty("createdBy").excludeProperty("modifiedBy").enableLike(MatchMode.START); //use like for string comparisons
            results = session.createCriteria(instance.getClass()).add(example).list();
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new LookupException("failed to findbynamedquery 1 ", hibernateException);
        } catch (SQLException sqlException) {
            throw new LookupException("failed to findbynamedquery 2", sqlException);
        }

        SessionFactory.getInstance().closeSession(session);

        return (results);

    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param value        the value of the property
     * @return the collection of instances
     * @throws LookupException if we failed to execute the query
     */

    public Collection findByPropertyValue(String propertyName, Object value) throws LookupException {

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        return session.createCriteria(this.getPersistentClass()).add(Expression.eq(propertyName, value)).list();
    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param values       the value of the property
     * @return the collection of instances
     * @throws LookupException if we failed to execute the query
     */

    public Collection findByPropertyValues(String propertyName, Object[] values) throws LookupException {
        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        return session.createCriteria(this.getPersistentClass()).add(Restrictions.in(propertyName, values)).list();
    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param values       the value of the property
     * @return the collection of instances
     * @throws LookupException if we failed to execute the query
     */

    public Collection findByPropertyValuesLongSession(String propertyName, Object[] values) throws LookupException {
        longSession = SessionFactory.getInstance()
                .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
        return longSession.createCriteria(this.getPersistentClass()).add(Restrictions.in(propertyName, values))
                .list();
    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param value        the value of the property
     * @return the collection of instances
     * @throws LookupException if we failed to execute the query
     */

    public DomainObject findByUniquePropertyValue(String propertyName, Object value) throws LookupException {

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        DomainObject domainObject = (DomainObject) session.createCriteria(this.getPersistentClass())
                .add(Expression.eq(propertyName, value)).uniqueResult();
        session.close();
        return domainObject;
    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param value        the value of the property
     * @return the collection of instances
     * @throws LookupException if we failed to execute the query
     */

    public DomainObject findByUniquePropertyValueLongSession(String propertyName, Object value)
            throws LookupException {
        longSession = SessionFactory.getInstance()
                .openSession(new AuditInterceptor(ApplicationFrame.getInstance().getCurrentUser()));
        DomainObject domainObject = (DomainObject) longSession.createCriteria(this.getPersistentClass())
                .add(Expression.eq(propertyName, value)).uniqueResult();
        return domainObject;
    }

    /**
     * Find instances through a named query without parameters.
     *
     * @param propertyName the name of the property
     * @param oldValue     the old value of the property
     * @param newValue     the new value of the property
     * @return the number of records updated
     * @throws LookupException if we failed to execute the query
     */

    public int updateTextField(String propertyName, String oldValue, String newValue,
            InfiniteProgressPanel progressPanel)
            throws LookupException, IllegalAccessException, InvocationTargetException, ValidationException {
        Session session = SessionFactory.getInstance().openSession();
        Transaction tx = session.beginTransaction();
        ATValidator validator;
        ValidationResult validationResult;

        Collection records = session.createCriteria(this.getPersistentClass())
                .add(Expression.eq(propertyName, oldValue)).list();
        int updatedEntities = records.size();
        int count = 1;
        int textDepth = progressPanel.getTextDepth();
        String message;
        for (Object record : records) {
            message = count++ + " of " + updatedEntities;
            progressPanel.setTextLine(message, textDepth + 1);
            BeanUtils.setProperty(record, propertyName, newValue);
            validator = ValidatorFactory.getInstance().getValidator((DomainObject) record);
            if (validator != null) {
                validationResult = validator.validate();
                if (validationResult.hasErrors()) {
                    // we have an error so roll back the transaction and throw an error
                    tx.rollback();
                    session.close();
                    throw new ValidationException("For the record named \"" + record.toString() + "\"\n"
                            + validationResult.getMessagesText());
                }
            }

            session.update(record);
        }
        tx.commit();
        session.close();
        return updatedEntities;
    }

    public Integer getCountBasedOnPropertyValue(String propertyName, Object value) {
        Session session = SessionFactory.getInstance().openSession();
        Criteria criteria = session.createCriteria(this.getPersistentClass()).setProjection(Projections.rowCount())
                .add(Expression.eq(propertyName, value));
        Integer count = (Integer) criteria.list().get(0);
        session.close();
        return count;
    }

    public int merge(Collection<DomainObject> mergeFrom, DomainObject mergeTo, InfiniteProgressPanel progressPanel)
            throws MergeException {
        return 0;
    }

    /**
     * Return a collection which conforms to the named query.
     * TODO: check the bean interface to queries
     *
     * @param queryName      the name of the query
     * @param propertyObject the bean which is used to pass properties to the query
     * @return the collection generated by the query
     * @throws LookupException fails if we cannot execute the named query
     */

    public final Collection findByNamedQuery(final String queryName, final Object propertyObject)
            throws LookupException {
        List filteredList;

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());
        try {
            Query query = session.getNamedQuery(queryName);

            query.setProperties(propertyObject);

            filteredList = query.list();
            session.flush();
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new LookupException("failed to findbynamedquery 1", hibernateException);
        } catch (SQLException sqlException) {
            throw new LookupException("failed to findbynamedquery 2", sqlException);
        }

        SessionFactory.getInstance().closeSession(session);

        return (filteredList);
    }

    /**
     * Return a collection which conforms to the named query.
     *
     * @param queryName the name of the query
     * @return the collection provided by the query
     * @throws LookupException fails if we cannot execute the query
     */

    public final Collection findByNamedQuery(final String queryName) throws LookupException {
        List filteredList;

        Session session = SessionFactory.getInstance().openSession(getPersistentClass());

        try {
            //session.connection().setReadOnly(true);
            session.setFlushMode(FlushMode.MANUAL);

            Query query = session.getNamedQuery(queryName);

            filteredList = query.list();
            //session.flush();  Don't flush here this causes all sorts of hell on Oracle
            session.connection().commit();

        } catch (HibernateException hibernateException) {
            throw new LookupException("failed to findbynamedquery", hibernateException);
        } catch (SQLException sqlException) {
            throw new LookupException("failed to findbynamedquery", sqlException);
        }

        SessionFactory.getInstance().closeSession(session);

        return (filteredList);
    }

    /**
     * Called to notify the listener that an event has occurred.
     *
     * @param event denotes that a domainobject has changed.
     */

    public final void domainChanged(final DomainAccessEvent event) {
        this.notifyListeners(event);
    }

    protected Class getPersistentClass() {
        return persistentClass;
    }

    private void updateClassSpecific(DomainObject object, Session session)
            throws NoSuchAlgorithmException, UnsupportedEncodingException {
        if (object instanceof DatabaseTables) {
            ((DatabaseTables) object).reorderReturnScreenList();
        } else if (object instanceof Users) {
            if (ApplicationFrame.getInstance().getCurrentUser().equals(object)) {
                ApplicationFrame.getInstance().setCurrentUser((Users) object);
            }
        } else if (object instanceof Resources) {
            ResourcesComponentsDAO dao = new ResourcesComponentsDAO();
            for (ResourcesComponents component : ((Resources) object).getComponentsToDelete()) {
                dao.deleteComponent(component, session);
            }
            // must clear all components that were deleted so that we don't get a bug
            ((Resources) object).clearComponentsToDelete();
        } else if (object instanceof Names) {
            Names name = (Names) object;
            NameUtils.setMd5Hash(name);
        }
    }

    public String getHumanReadableSearchString() {
        return humanReadableSearchString;
    }

    public void setHumanReadableSearchString(String humanReadableSearchString) {
        this.humanReadableSearchString = humanReadableSearchString;
    }
}