podd.util.PoddWebappTestUtil.java Source code

Java tutorial

Introduction

Here is the source code for podd.util.PoddWebappTestUtil.java

Source

/*
 * Copyright (c) 2009 - 2010. School of Information Technology and Electrical
 * Engineering, The University of Queensland.  This software is being developed
 * for the "Phenomics Ontoogy Driven Data Management Project (PODD)" project.
 * PODD is a National e-Research Architecture Taskforce (NeAT) project
 * co-funded by ANDS and ARCS.
 *
 * PODD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PODD 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
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PODD.  If not, see <http://www.gnu.org/licenses/>.
 */

package podd.util;

import info.aduna.collections.iterators.CloseableIterator;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.semanticweb.owl.model.AddAxiom;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLClassAssertionAxiom;
import org.semanticweb.owl.model.OWLDataFactory;
import org.semanticweb.owl.model.OWLIndividual;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOntologyAnnotationAxiom;
import org.semanticweb.owl.model.OWLOntologyChangeException;
import org.semanticweb.owl.model.OWLOntologyManager;
import org.semanticweb.owl.model.OWLSubClassAxiom;
import org.springframework.security.providers.encoding.PasswordEncoder;
import podd.dataaccess.EntityDAO;
import podd.dataaccess.PoddConceptDAO;
import podd.dataaccess.PoddObjectDAO;
import podd.dataaccess.RepositoryRoleDAO;
import podd.dataaccess.UserDAO;
import podd.dataaccess.UserProjectRoleBundleDAO;
import podd.dataaccess.hibernate.HibernateSessionHelper;
import podd.exception.DataAccessException;
import podd.exception.EntityException;
import podd.exception.MimeTypeHandlingException;
import podd.exception.RepositoryObjectHandlingException;
import podd.exception.VersioningException;
import podd.model.data.DataItem;
import podd.model.data.impl.ManagedDataItemImpl;
import podd.model.data.versioning.impl.VersionImpl;
import podd.model.entity.PoddConcept;
import podd.model.entity.PoddEntity;
import podd.model.entity.PoddObject;
import podd.model.project.Project;
import podd.model.user.User;
import podd.model.user.UserProjectRoleBundle;
import podd.model.user.impl.UserImpl;
import podd.util.common.Constants;
import podd.util.owl.OntologyHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.restlet.engine.Engine.getClassLoader;
import static org.semanticweb.owl.vocab.OWLRDFVocabulary.OWL_VERSION_INFO;
import static podd.model.user.ProjectRole.PRINCIPAL_INVESTIGATOR;
import static podd.model.user.RepositoryRole.PROJECT_CREATOR;
import static podd.model.user.RepositoryRole.PUBLIC;
import static podd.model.user.RepositoryRole.REPOSITORY_ADMINISTRATOR;
import static podd.model.user.RepositoryRole.REPOSITORY_USER;
import static podd.model.user.UserStatus.ACTIVE;
import static podd.util.common.vocabulary.PoddModelNamespace.PODD_MODEL;
import static podd.util.db.HibernateSessionFactoryUtil.closeSession;
import static podd.util.db.HibernateSessionFactoryUtil.currentSession;
import static podd.util.fedora.FedoraRepositoryUtil.getCurrentTimeAsString;

/**
 * @author Yuan-Fang Li
 * @version $Id$
 */

public class PoddWebappTestUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(PoddWebappTestUtil.class);
    private static final PoddApplicationContext PODD_CONTEXT = PoddApplicationContext.getPoddContext();
    private static final PoddWebApplicationContext PODD_WEB_CONTEXT = PoddWebApplicationContext.getPoddContext();

    private static final PasswordEncoder PASSWORD_ENCODER = PODD_WEB_CONTEXT.getPasswordEncoder();
    private static final OntologyHelper ONT_HELPER = PODD_CONTEXT.getOntologyHelper();
    private static final OWLOntologyManager MANAGER = ONT_HELPER.getManager();
    private static final OWLDataFactory DATA_FACTORY = MANAGER.getOWLDataFactory();

    public static void clearDBs() {
        //clearDB(PoddObjectImpl.class.getName());
        //clearDB(ProjectImpl.class.getName());
        //clearDB(PoddConceptImpl.class.getName());
        clearDB(PoddEntity.class.getName());
        //clearDB(User.class.getName());
    }

    public static void clearDB(String className) {
        try {
            Session session = currentSession();
            session.beginTransaction();
            Query query = session.createQuery("from " + className);
            int size = 0;
            for (Object obj : query.list()) {
                session.delete(obj);
                size++;
            }
            LOGGER.debug("Rows affected: " + size);
            session.getTransaction().commit();
            closeSession();
        } catch (HibernateException e) {
            throw new RuntimeException(e);
        }
    }

    public static void deleteObject(PoddObject object) {
        if (null != object) {
            Session session = currentSession();
            try {
                session.beginTransaction();
                doDeleteObject(object, session);
                session.getTransaction().commit();
                PODD_CONTEXT.getFedoraUtil().purgeObject(object.getPid(), "delete test object");
            } catch (HibernateException e) {
                session.getTransaction().rollback();
                throw new RuntimeException(e);
            } catch (RepositoryObjectHandlingException e) {
                throw new RuntimeException(e);
            } finally {
                closeSession();
            }
        }
    }

    private static void doDeleteObject(PoddObject object, Session session) {
        final Criteria criteria = session.createCriteria(PoddObject.class)
                .add(Restrictions.eq("pid", object.getPid()));
        object = (PoddObject) criteria.uniqueResult();
        if (null != object) {
            final Set<PoddObject> children = new HashSet<PoddObject>();
            for (PoddObject mem : object.getMembers()) {
                children.add(mem);
            }
            for (PoddObject child : children) {
                object.removeMember(child);
                child.setContainer(null);
                doDeleteObject(child, session);
            }
            session.delete(object);
            LOGGER.debug("Object deleted: " + object.getPid());
        }
    }

    public static User populateUser(String userName, String email) {
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("UserName", userName);
            map.put("RepositoryRole", REPOSITORY_ADMINISTRATOR);
            map.put("PasswordHash", PASSWORD_ENCODER.encodePassword(getAdminProperty("password"), userName));
            map.put("FirstName", getAdminProperty("firstname"));
            map.put("LastName", getAdminProperty("lastname"));
            map.put("Email", email);
            map.put("Status", ACTIVE);
            map.put("Label", "new user object");
            map.put("Affiliation", getAdminProperty("institution"));
            map.put("Homepage", getAdminProperty("homepage"));
            map.put("PhoneNumber", getAdminProperty("phone"));
            map.put("CreatedTime", getCurrentTimeAsString());
            return createUser(map);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static User createUser(Map<String, Object> map) {
        try {
            Method[] methods = User.class.getMethods();
            Map<String, Method> methodMap = new HashMap<String, Method>();
            for (Method mtd : methods) {
                methodMap.put(mtd.getName(), mtd);
            }
            User user = new UserImpl();

            for (String key : map.keySet()) {
                String methodName = "set" + key;
                final Method method = methodMap.get(methodName);
                Object value = map.get(key);
                method.invoke(user, value);
            }
            return user;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void setupDefaultRepoRoles() {
        RepositoryRoleDAO dao = PODD_CONTEXT.getRepositoryRoleDAO();
        try {
            dao.save(PUBLIC);
            dao.save(REPOSITORY_USER);
            dao.save(PROJECT_CREATOR);
            dao.save(REPOSITORY_ADMINISTRATOR);
        } catch (DataAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static PoddConcept createConceptOntologyWithSubClass(PoddConcept concept) throws Exception {
        URI conceptUri = URI.create(PODD_MODEL.uri + concept.getConceptName());
        OWLClass conceptCls = DATA_FACTORY.getOWLClass(conceptUri);
        URI experimentURI = URI.create(PODD_MODEL.uri + "Experiment");
        final OWLClass experimentClass = DATA_FACTORY.getOWLClass(experimentURI);
        final OWLSubClassAxiom subClassAxiom = DATA_FACTORY.getOWLSubClassAxiom(conceptCls, experimentClass);

        OWLOntology ontology = concept.getCurrentDefinition();
        ontology = ONT_HELPER.applyChanges(ontology,
                Collections.singletonList(new AddAxiom(ontology, subClassAxiom)));
        concept.setCurrentDefinition(ontology);
        return concept;
    }

    public static PoddConcept createConcept(PoddConcept concept, String name, User user) throws Exception {
        concept.setCreator(user);
        concept.setConceptName(name);
        concept.setLabel("The new concept: " + name);
        concept.setCreatedTime(getCurrentTimeAsString());
        concept = createConceptOntologyWithSubClass(concept);
        return concept;
    }

    public static PoddConcept loadConcept(String name) throws DataAccessException {
        final CloseableIterator<PoddConcept> iterator = PODD_CONTEXT.getPoddConceptDAO().loadByLocalName(name);
        try {
            if (iterator.hasNext()) {
                return iterator.next();
            }
            return null;
        } finally {
            iterator.close();
        }
    }

    public static PoddObject createSaveObject(User testAdmin, String projectName, String conceptName)
            throws Exception {
        PoddConcept poddConcept = loadConcept(conceptName);
        Project object = PODD_CONTEXT.getEntityFactory().createProject(testAdmin);
        object = prepareObject(object, projectName, poddConcept);
        PODD_CONTEXT.getProjectRoleBundleDAO().saveBundle(testAdmin.getUserName(), object.getPid(),
                PRINCIPAL_INVESTIGATOR.toString());
        PODD_CONTEXT.getPoddObjectDAO().save(object);
        return object;
    }

    public static User saveUser(String userName, String email, String roleName) throws DataAccessException {
        final UserDAO userDao = PODD_CONTEXT.getUserDAO();
        User user = userDao.loadByUserName(userName);
        if (null == user) {
            user = populateUser(userName, email);
            user.setRepositoryRole(PODD_CONTEXT.getRepositoryRoleDAO().getRepositoryRole(roleName));
            userDao.save(user);
        } else {
            user.setEmail(email);
            user.setRepositoryRole(PODD_CONTEXT.getRepositoryRoleDAO().getRepositoryRole(roleName));
            userDao.update(user);
        }
        return user;
    }

    public static void attachFile(User testAdmin, PoddObject object, String fileName, String desc)
            throws IOException, VersioningException, EntityException, MimeTypeHandlingException {
        final DataItem dataItem = new ManagedDataItemImpl(fileName);
        final URL url = object.getClass().getClassLoader().getResource(fileName);
        final File tempFile = File.createTempFile("podd-temp", "abc");
        tempFile.createNewFile();
        tempFile.deleteOnExit();
        final File file = new File(url.getFile());
        assertTrue(file.exists());
        FileUtils.copyFile(file, tempFile);
        dataItem.addVersion(new VersionImpl<URL>(getCurrentTimeAsString(),
                PODD_CONTEXT.getMimeTypeDetector().getMimeType(tempFile), tempFile.toURI().toURL(), desc,
                testAdmin.getUserName()));
        object.addDataItem(fileName, dataItem);

    }

    public static <T extends PoddObject> T prepareObject(T object, String name, PoddConcept concept)
            throws Exception {
        object.setObjectName(name);
        object.setConcept(concept);
        object.setLabel("New object: " + name);
        object = addMapsToAssertion(object, concept.getCurrentDefinition());
        return object;
    }

    private static <T extends PoddObject> T addMapsToAssertion(T object, OWLOntology conceptOntology)
            throws OWLOntologyChangeException, VersioningException {
        OWLOntology ontology = object.getCurrentRelations();
        final Iterator<OWLOntologyAnnotationAxiom> iterator = ONT_HELPER.getOntologyAnnotations(conceptOntology,
                OWL_VERSION_INFO.getURI(), null);
        if (iterator.hasNext()) {
            final String timestamp = iterator.next().getAnnotation().getAnnotationValueAsConstant().getLiteral();
            ontology = ONT_HELPER.addOntologyAnnotationAssertion(ontology, PODD_MODEL.MAPS_TO_VERSION.getURI(),
                    timestamp);
            object.setCurrentRelations(ontology);
        }
        final Set<OWLSubClassAxiom> set = conceptOntology
                .getSubClassAxiomsForRHS(DATA_FACTORY.getOWLClass(PODD_MODEL.PODD_CONCEPT.getURI()));
        final OWLIndividual individual = DATA_FACTORY
                .getOWLIndividual(URI.create(Constants.PODD_OBJECT_NAMESPACE + object.getPid()));
        if (!set.isEmpty()) {
            final OWLClass conceptClass = set.iterator().next().getSubClass().asOWLClass();
            final OWLClassAssertionAxiom axiom = DATA_FACTORY.getOWLClassAssertionAxiom(individual, conceptClass);
            MANAGER.addAxiom(ontology, axiom);
        }
        return object;
    }

    public static String getAdminProperty(String key) throws IOException {
        Properties adminProperties = new Properties();
        final URL url = getClassLoader().getResource("test.admin.properties");
        FileInputStream in = new FileInputStream(new File(url.getFile()));
        adminProperties.load(in);
        in.close();
        return adminProperties.get(key).toString();
    }

    public static void deleteTestAdminUser() {
        try {
            HibernateSessionHelper.openSession(PODD_CONTEXT.getSessionFactory());

            UserDAO userDao = PODD_CONTEXT.getUserDAO();
            String username = getAdminProperty("username");
            User adminuser = userDao.loadByUserName(username);

            if (adminuser != null) {
                // Delete any projects associated with this user that haven't been deleted
                UserProjectRoleBundleDAO projectRoleBundleDao = PODD_CONTEXT.getProjectRoleBundleDAO();
                Set<UserProjectRoleBundle> userProjectRoles = projectRoleBundleDao.getUserProjectRole(username);
                if (userProjectRoles != null) {
                    for (UserProjectRoleBundle userProjectRoleBundle : userProjectRoles) {
                        projectRoleBundleDao.delete(userProjectRoleBundle);
                    }
                }

                // Delete any podd objects associated with this user that haven't been deleted
                EntityDAO entityDao = PODD_CONTEXT.getPIDHolderDAO();
                PoddObjectDAO poddObjectDao = PODD_CONTEXT.getPoddObjectDAO();
                PoddConceptDAO poddConceptDao = PODD_CONTEXT.getPoddConceptDAO();

                CloseableIterator<PoddEntity> poddEntities = entityDao.getByCreator(adminuser);
                Set<PoddConcept> concepts = new HashSet<PoddConcept>();
                if (poddEntities != null) {
                    while (poddEntities.hasNext()) {
                        PoddEntity entity = poddEntities.next();

                        // First delete the Podd object associated with this podd entity
                        PoddObject poddObject = poddObjectDao.load(entity.getPid());
                        if (poddObject != null) {
                            //deleteObject(poddObject);
                            deleteObject(entityDao, poddObjectDao, poddObject);

                        }

                        // Delete the podd concept associated with this podd entity
                        if (null == poddObject) {
                            PoddConcept poddConcept = poddConceptDao.load(entity.getPid());
                            if (poddConcept != null) {
                                concepts.add(poddConcept);
                            }
                        }
                    }
                }

                for (PoddConcept concept : concepts) {
                    poddConceptDao.delete(concept);
                    entityDao.delete(concept);
                }

                // Now finally delete the admin user
                userDao.delete(adminuser);
            }
        } catch (Exception ignore) {
            LOGGER.warn("*************** Unable to delete test admin user. ", ignore);
        } finally {
            HibernateSessionHelper.closeSession(PODD_CONTEXT.getSessionFactory());
        }
    }

    private static void cascadeDelete(PoddObject poddObject, EntityDAO entityDAO, PoddObjectDAO poddObjectDAO)
            throws DataAccessException {
        for (PoddObject member : poddObject.getMembers()) {
            member.setContainer(null);
            entityDAO.update(member);

        }
    }

    private static void deleteObject(EntityDAO entityDao, PoddObjectDAO poddObjectDao, PoddObject poddObject)
            throws DataAccessException {
        // detach the object from its parent (container)
        PoddObject container = poddObject.getContainer();
        if (null != container) {
            poddObject.setContainer(null);
            container.getMembers().remove(poddObject);
            entityDao.update(container);
        }
        // detach the object from its members
        for (PoddObject member : poddObject.getMembers()) {
            member.setContainer(null);
            entityDao.update(member);
        }
        poddObject.setMembers(null);
        entityDao.update(poddObject);
        LOGGER.info("Deleting " + poddObject.toString() + ", ID = " + poddObject.getId() + ", members: "
                + poddObject.getMembers() + ", container = " + poddObject.getContainer());
        poddObjectDao.forceDelete(poddObject);
    }

    public static <T> void checkMembers(boolean checkGetterMethods, Set<String> skipList, Collection<T> collection,
            T... instances) {
        if (null == instances) {
            assertTrue(collection.isEmpty());
        } else {
            assertEquals(instances.length, collection.size());
            for (T instance : instances) {
                assertTrue("Containing: " + instance, collection.contains(instance));
            }
            if (checkGetterMethods) {
                for (T obj1 : collection) {
                    for (T obj2 : instances) {
                        if (obj1.equals(obj2)) {
                            checkGetterMethods(obj1, obj2, skipList);
                            break;
                        }
                    }
                }
            }
        }
    }

    @SuppressWarnings({ "unchecked" })
    public static <T> void checkGetterMethods(T obj1, T obj2, Set<String> skipList) {
        try {
            final Method[] methods = obj1.getClass().getMethods();
            for (Method m : methods) {
                if (m.getName().startsWith("get") && !skipList.contains(m.getName())) {
                    final Object value1 = m.invoke(obj1);
                    final Object value2 = m.invoke(obj2);
                    if (value1 instanceof Collection && value2 instanceof Collection) {
                        checkMembers((Collection) value1, ((Collection) value2).toArray());
                    } else if (!(value1 instanceof Collection || value2 instanceof Collection)) {
                        assertEquals("Method: " + m.getName(), value1, value2);
                    } else {
                        throw new IllegalArgumentException("One is collection while the other is not.");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> void checkMembers(Collection<T> collection, T... instances) {
        if (null == instances) {
            assertTrue(collection.isEmpty());
        } else {
            assertEquals(instances.length, collection.size());
            for (T bundle : instances) {
                assertTrue(collection.contains(bundle));
            }
        }
    }
}