Java tutorial
/* * 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)); } } } }