diff --git a/ccm-core/pom.xml b/ccm-core/pom.xml index 704b666a2..b4f7099aa 100644 --- a/ccm-core/pom.xml +++ b/ccm-core/pom.xml @@ -43,6 +43,11 @@ hibernate-entitymanager + + org.hibernate + hibernate-envers + + org.hibernate hibernate-validator diff --git a/ccm-core/src/main/java/org/libreccm/auditing/AbstractAuditedEntityRepository.java b/ccm-core/src/main/java/org/libreccm/auditing/AbstractAuditedEntityRepository.java new file mode 100644 index 000000000..5099e75ea --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/auditing/AbstractAuditedEntityRepository.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.auditing; + +import org.hibernate.envers.AuditReader; +import org.hibernate.envers.query.AuditEntity; +import org.hibernate.envers.query.AuditQuery; +import org.libreccm.core.AbstractEntityRepository; + +import javax.inject.Inject; + +/** + * + * @author Jens Pelzetter + * @param Primary key of the entity. + * @param Type of the entity + */ +public abstract class AbstractAuditedEntityRepository + extends AbstractEntityRepository { + + @Inject + private transient AuditReader auditReader; + + public abstract K getEntityId(final T entity); + + public T retrieveRevisionOfEntity(final T entity, final Number revision) { + final AuditQuery query = auditReader.createQuery() + .forEntitiesAtRevision(getEntityClass(), revision); + query.add(AuditEntity.id().eq(getEntityId(entity))); + + final Object result = query.getSingleResult(); + + if (getEntityClass().isInstance(result)) { + return (T) result; + } else { + throw new AuditQueryException(String.format( + "The result is not an instance of the entity class. " + + "Entity class: \"%s\"; Result class: \"%s\"", + getEntityClass().getName(), + result.getClass().getName()) + ); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/auditing/AuditQueryException.java b/ccm-core/src/main/java/org/libreccm/auditing/AuditQueryException.java new file mode 100644 index 000000000..4af78718d --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/auditing/AuditQueryException.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +package org.libreccm.auditing; + +/** + * + * @author Jens Pelzetter + */ +public class AuditQueryException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of AuditQueryException without detail message. + */ + public AuditQueryException() { + super(); + } + + + /** + * Constructs an instance of AuditQueryException with the specified detail message. + * + * @param msg The detail message. + */ + public AuditQueryException(final String msg) { + super(msg); + } + + /** + * Constructs an instance of AuditQueryException which wraps the + * specified exception. + * + * @param exception The exception to wrap. + */ + public AuditQueryException(final Exception exception) { + super(exception); + } + + /** + * Constructs an instance of AuditQueryException with the specified message which also wraps the + * specified exception. + * + * @param msg The detail message. + * @param exception The exception to wrap. + */ + public AuditQueryException(final String msg, final Exception exception) { + super(msg, exception); + } +} diff --git a/ccm-core/src/main/java/org/libreccm/auditing/CcmRevision.java b/ccm-core/src/main/java/org/libreccm/auditing/CcmRevision.java new file mode 100644 index 000000000..a7d150fed --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/auditing/CcmRevision.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.auditing; + +import org.hibernate.envers.DefaultRevisionEntity; +import org.hibernate.envers.RevisionEntity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +/** + * Revision entity for Hibernate Envers containing the editing user. We are not + * using an association between this class and the user class because the user + * may be deleted but the revisions will stay. Therefore we use the value of the + * screenname property here. + * + * @author Jens Pelzetter + */ +@Entity +@Table(name = "ccm_revisions") +@RevisionEntity() +public class CcmRevision extends DefaultRevisionEntity { + + private static final long serialVersionUID = -3458682765535922544L; + + @Column(name = "user_name") + private String userName; + + public String getUserName() { + return userName; + } + + public void setUserName(final String userName) { + this.userName = userName; + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/auditing/CcmRevisionListener.java b/ccm-core/src/main/java/org/libreccm/auditing/CcmRevisionListener.java new file mode 100644 index 000000000..c581f39c3 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/auditing/CcmRevisionListener.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.auditing; + +import org.hibernate.envers.RevisionListener; +import org.libreccm.core.CcmSessionContext; +import org.libreccm.core.Subject; +import org.libreccm.core.User; + +import javax.inject.Inject; + +/** + * {@link RevisionListener} setting the user for the {@link CcmRevision} entity. + * + * @author Jens Pelzetter + */ +public class CcmRevisionListener implements RevisionListener { + + @Inject + private transient CcmSessionContext sessionContext; + + @Override + public void newRevision(final Object revisionEntity) { + if (!(revisionEntity instanceof CcmRevision)) { + throw new IllegalArgumentException(String.format( + "Provided revision entity is not an instance of class \"%s\".", + CcmRevision.class.getName())); + } + + final CcmRevision revision = (CcmRevision) revisionEntity; + final Subject subject = sessionContext.getCurrentSubject(); + if (subject instanceof User) { + final User user = (User) subject; + revision.setUserName(user.getScreenName()); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/auditing/package-info.java b/ccm-core/src/main/java/org/libreccm/auditing/package-info.java new file mode 100644 index 000000000..44dd459e2 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/auditing/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +/** + * This package contains supplemental classes for auditing entities using + * Hibernate Envers. + */ +package org.libreccm.auditing; diff --git a/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java b/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java index be369c1de..53d6acfb6 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/CategoryManager.java @@ -79,6 +79,7 @@ public class CategoryManager { public void addObjectToCategory(final CcmObject object, final Category category, final long order) { + // TODO implement method throw new UnsupportedOperationException(); } @@ -105,6 +106,7 @@ public class CategoryManager { public void removeObjectFromCategory(final CcmObject object, final Category category) throws ObjectNotAssignedToCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -125,6 +127,7 @@ public class CategoryManager { public void increaseObjectOrder(final CcmObject object, final Category category) throws ObjectNotAssignedToCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -145,6 +148,7 @@ public class CategoryManager { public void decreaseObjectOrder(final CcmObject object, final Category category) throws ObjectNotAssignedToCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -167,6 +171,7 @@ public class CategoryManager { final CcmObject objectB, final Category category) throws ObjectNotAssignedToCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -200,6 +205,7 @@ public class CategoryManager { public void addSubCategoryToCategory(final Category subCategory, final Category parentCategory, final long order) { + // TODO implement method throw new UnsupportedOperationException(); } @@ -219,6 +225,7 @@ public class CategoryManager { public void removeSubCategoryFromCategory(final Category subCategory, final Category parentCategory) throws NotASubCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -240,6 +247,7 @@ public class CategoryManager { public void increaseCategoryOrder(final Category subCategory, final Category parentCategory) throws NotASubCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -261,6 +269,7 @@ public class CategoryManager { public void decreaseCategoryOrder(final Category subCategory, final Category parentCategory) throws NotASubCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } @@ -279,6 +288,7 @@ public class CategoryManager { final Category subCategoryB, final Category parentCategory) throws NotASubCategoryException { + // TODO implement method throw new UnsupportedOperationException(); } diff --git a/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java b/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java index 59330d80a..7e4ae67ae 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java @@ -63,6 +63,7 @@ public class CategoryRepository extends AbstractEntityRepository * empty. */ public List getOrphanedCategories() { + // TODO implement method throw new UnsupportedOperationException(); } diff --git a/ccm-core/src/main/java/org/libreccm/categorization/DomainManager.java b/ccm-core/src/main/java/org/libreccm/categorization/DomainManager.java index c1de518f8..fb53861cd 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/DomainManager.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/DomainManager.java @@ -47,6 +47,7 @@ public class DomainManager { */ public void addDomainOwner(final Application application, final Domain domain) { + // TODO implement method throw new UnsupportedOperationException(); } @@ -62,6 +63,7 @@ public class DomainManager { */ public void removeDomainOwner(final Application application, final Domain domain) { + // TODO implement method throw new UnsupportedOperationException(); } @@ -75,6 +77,7 @@ public class DomainManager { */ public boolean isDomainOwner(final Application application, final Domain domain) { + // TODO implement method throw new UnsupportedOperationException(); } diff --git a/ccm-core/src/main/java/org/libreccm/categorization/DomainRepository.java b/ccm-core/src/main/java/org/libreccm/categorization/DomainRepository.java index 520082383..c4dfc7dce 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/DomainRepository.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/DomainRepository.java @@ -56,6 +56,7 @@ public class DomainRepository extends AbstractEntityRepository { * {@code null} if there is no such {@code Domain}. */ public Domain findByDomainKey(final String domainKey) { + // TODO implement method throw new UnsupportedOperationException(); } @@ -68,6 +69,7 @@ public class DomainRepository extends AbstractEntityRepository { * if there is so such {@code Domain}. */ public Domain findByUri(final URI uri) { + // TODO implement method throw new UnsupportedOperationException(); } diff --git a/ccm-core/src/main/java/org/libreccm/jpa/EntityManagerProducer.java b/ccm-core/src/main/java/org/libreccm/jpa/EntityManagerProducer.java index acc13b036..cd2c36572 100644 --- a/ccm-core/src/main/java/org/libreccm/jpa/EntityManagerProducer.java +++ b/ccm-core/src/main/java/org/libreccm/jpa/EntityManagerProducer.java @@ -1,5 +1,8 @@ package org.libreccm.jpa; +import org.hibernate.envers.AuditReader; +import org.hibernate.envers.AuditReaderFactory; + import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.persistence.EntityManager; @@ -17,4 +20,7 @@ public class EntityManagerProducer { @PersistenceContext(name = "LibreCCM") private EntityManager entityManager; + @Produces + private AuditReader auditReader = AuditReaderFactory.get(entityManager); + } diff --git a/ccm-core/src/main/java/org/libreccm/modules/Bar.java b/ccm-core/src/main/java/org/libreccm/modules/Bar.java new file mode 100644 index 000000000..93770758c --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/Bar.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +/** + * + * @author Jens Pelzetter + */ +public class Bar implements Module { + + @Override + public void prepare() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void uninstall() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void init() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/Example.java b/ccm-core/src/main/java/org/libreccm/modules/Example.java new file mode 100644 index 000000000..606181e19 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/Example.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +/** + * + * @author Jens Pelzetter + */ +public class Example implements Module { + + @Override + public void prepare() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void uninstall() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void init() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/Foo.java b/ccm-core/src/main/java/org/libreccm/modules/Foo.java new file mode 100644 index 000000000..738a25689 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/Foo.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +import org.libreccm.modules.annotations.RequiredModule; + +/** + * + * @author Jens Pelzetter + */ +@org.libreccm.modules.annotations.Module(name = "org.libreccm.foo.Foo", + version = "1.0.0-beta.1", + requiredModules = { + @RequiredModule(module = Bar.class, version = "1.0.0"), + @RequiredModule(module= Example.class, version = "6.6.7")}) +public class Foo implements Module { + + @Override + public void prepare() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void uninstall() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void init() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/Module.java b/ccm-core/src/main/java/org/libreccm/modules/Module.java new file mode 100644 index 000000000..d8cf09005 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/Module.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +/** + * + * @author Jens Pelzetter + */ +public interface Module { + + /** + * Called by the {@link ModuleManager} after the database tables for the + * module have been created. Use this method to create initial or example + * data. + */ + void prepare(); + + /** + * Called by the {@link ModuleManager} when a module is removed from the + * installation. If necessary clean up the data of the module in the + * implementation of this method. + */ + void uninstall(); + + /** + * Called each time the CCM application is started. Use an implementation of + * this method for creating static instances or for integrity checking. + */ + void init(); + + /** + * Called each time the CCM application stops. + */ + void shutdown(); + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/ModuleManager.java b/ccm-core/src/main/java/org/libreccm/modules/ModuleManager.java new file mode 100644 index 000000000..6731765c1 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/ModuleManager.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; + +/** + * + * @author Jens Pelzetter + */ +@ApplicationScoped +public class ModuleManager { + + @Inject + private transient Instance modules; + + + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/ModuleUtil.java b/ccm-core/src/main/java/org/libreccm/modules/ModuleUtil.java new file mode 100644 index 000000000..3a0807bf6 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/ModuleUtil.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules; + +import org.libreccm.modules.annotations.RequiredModule; + +/** + * + * @author Jens Pelzetter + */ +public class ModuleUtil { + + private ModuleUtil() { + //Nothing + } + + private static org.libreccm.modules.annotations.Module getModuleAnnotation( + final Module module) { + final org.libreccm.modules.annotations.Module annotation = module + .getClass().getAnnotation( + org.libreccm.modules.annotations.Module.class); + + if (annotation == null) { + throw new IllegalArgumentException(String.format( + "The provided implementation of the " + + "org.libreccm.modules.Module interface, \"%s\", is not" + + "annotated with org.libreccm.modules.annotations.Module", + module.getClass().getName())); + } else { + return annotation; + } + } + + public static String getModuleName(final Module module) { + return getModuleAnnotation(module).name(); + } + + public static String getVersion(final Module module) { + return getModuleAnnotation(module).version(); + } + + public static RequiredModule[] getRequiredModules(final Module module) { + return getModuleAnnotation(module).requiredModules(); + } + + public static String getModuleName(Class module) { + final org.libreccm.modules.annotations.Module annotation = module + .getAnnotation(org.libreccm.modules.annotations.Module.class); + + if (annotation == null) { + throw new IllegalArgumentException(String.format( + "The provided implementation of the " + + "org.libreccm.modules.Module interface, \"%s\", is not" + + "annotated with org.libreccm.modules.annotations.Module", + module.getClass().getName())); + } else { + return annotation.name(); + } + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/annotations/Module.java b/ccm-core/src/main/java/org/libreccm/modules/annotations/Module.java new file mode 100644 index 000000000..6015af003 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/annotations/Module.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.annotations; + +import org.jboss.as.server.moduleservice.ModuleDefinition; + +import static java.lang.annotation.ElementType.*; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.enterprise.util.Nonbinding; +import javax.inject.Qualifier; + +/** + * Annotate an implementation of the {@link ModuleDefinition} interface with + * this annotation to use it as a module. + * + * @author Jens Pelzetter + */ +@Target({METHOD, FIELD, PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Qualifier +public @interface Module { + + @Nonbinding String name() default ""; + + @Nonbinding String version() default ""; + + @Nonbinding RequiredModule[] requiredModules() default {}; + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/annotations/RequiredModule.java b/ccm-core/src/main/java/org/libreccm/modules/annotations/RequiredModule.java new file mode 100644 index 000000000..edc5c7741 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/annotations/RequiredModule.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.annotations; + +/** + * + * @author Jens Pelzetter + */ +public @interface RequiredModule { + + Class module(); + + String version() default ""; + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyException.java b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyException.java new file mode 100644 index 000000000..28bdabc26 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyException.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +package org.libreccm.modules.dependencytree; + +/** + * + * @author Jens Pelzetter + */ +public class DependencyException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of DependencyException without detail message. + */ + public DependencyException() { + super(); + } + + + /** + * Constructs an instance of DependencyException with the specified detail message. + * + * @param msg The detail message. + */ + public DependencyException(final String msg) { + super(msg); + } + + /** + * Constructs an instance of DependencyException which wraps the + * specified exception. + * + * @param exception The exception to wrap. + */ + public DependencyException(final Exception exception) { + super(exception); + } + + /** + * Constructs an instance of DependencyException with the specified message which also wraps the + * specified exception. + * + * @param msg The detail message. + * @param exception The exception to wrap. + */ + public DependencyException(final String msg, final Exception exception) { + super(msg, exception); + } +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyTreeManager.java b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyTreeManager.java new file mode 100644 index 000000000..648fc0660 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/DependencyTreeManager.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.libreccm.modules.Module; +import org.libreccm.modules.ModuleUtil; +import org.libreccm.modules.annotations.RequiredModule; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.enterprise.inject.Instance; + +/** + * + * @author Jens Pelzetter + */ +public class DependencyTreeManager { + + private static final Logger LOGGER = LogManager.getLogger( + DependencyTreeManager.class); + + public List generateTree(final Instance modules) throws + DependencyException { + + LOGGER.info("Starting to generate dependency tree..."); + + final Map nodes = new HashMap<>(); + + for (final Module module : modules) { + createTreeNode(module, nodes); + } + + for (final Module module : modules) { + addDependencyRelations(module, nodes); + } + + final List nodeList = new ArrayList<>(); + for (Map.Entry entry : nodes.entrySet()) { + nodeList.add(entry.getValue()); + } + + LOGGER.info("Dependency tree generated."); + + return nodeList; + } + + public List orderModules(final List dependencyTree) + throws DependencyException { + LOGGER.info("Creating an ordered list from the dependency tree..."); + + final List orderedModules = new ArrayList<>(); + final List resolvedModules = new ArrayList<>(); + + LOGGER.info("Looking for modules which do not depend on any other " + + "modules..."); + for (final TreeNode node : dependencyTree) { + if (node.getDependsOn().isEmpty()) { + LOGGER.info( + "\tModule \"{}\" does not depend on any other module", + ModuleUtil.getModuleName(node.getModule())); + resolvedModules.add(node); + } + } + + LOGGER.info("Ordering remaining nodes..."); + while (!resolvedModules.isEmpty()) { + + final TreeNode current = resolvedModules.remove(0); + LOGGER.info("\tProcessing node for module \"{}\"...", + ModuleUtil.getModuleName(current.getModule())); + + orderedModules.add(current); + + for (final TreeNode dependent : current.getDependentModules()) { + dependent.removeDependsOn(current); + + if (dependent.getDependsOn().isEmpty()) { + resolvedModules.add(dependent); + } + } + } + + if (orderedModules.size() == dependencyTree.size()) { + LOGGER.info("Dependency graph proceessed successfully. " + + "Modules in order:"); + for (final TreeNode node : orderedModules) { + LOGGER.info("\t{}", ModuleUtil.getModuleName(node.getModule())); + } + + return orderedModules; + } else { + LOGGER.fatal("The dependency graph has a least one cycle."); + throw new DependencyException( + "The dependency graph has a least one cycle."); + } + } + + private void createTreeNode(final Module module, + final Map nodes) { + final TreeNode node = new TreeNode(module); + + LOGGER.info("Creating node for module \"{}\"...", + ModuleUtil.getModuleName(module)); + nodes.put(ModuleUtil.getModuleName(module), node); + } + + private void addDependencyRelations(final Module module, + final Map nodes) + throws DependencyException { + + LOGGER.info("Adding dependency relations for module \"{}\"...", + ModuleUtil.getModuleName(module)); + + final String moduleName = ModuleUtil.getModuleName(module); + + if (!nodes.containsKey(moduleName)) { + LOGGER.fatal("Modules nodes map does contain an entry for \"{}\". " + + "That should not happen.", + ModuleUtil.getModuleName(module)); + throw new IllegalArgumentException(String.format( + "The nodes map does not contain a node for module \"%s\". " + + "That should not happen.", + moduleName)); + } + + final TreeNode node = nodes.get(moduleName); + LOGGER.info("Processing required modules for module \"{}\"...", + ModuleUtil.getModuleName(module)); + for (RequiredModule requiredModule : ModuleUtil.getRequiredModules( + module)) { + + LOGGER.info("\tModule \"{}\" requires module \"{}\".", + ModuleUtil.getModuleName(module), + ModuleUtil.getModuleName(requiredModule.module())); + + if (!nodes.containsKey(ModuleUtil.getModuleName(requiredModule + .module()))) { + + LOGGER.fatal("Required module \"{}\" no found.", + ModuleUtil.getModuleName(requiredModule.module())); + + throw new DependencyException(String.format( + "Module \"%s\" depends on module \"%s\" but the dependency " + + "tree does contain an entry for module \"%s\".", + ModuleUtil.getModuleName(module), + ModuleUtil.getModuleName(requiredModule.module()), + ModuleUtil.getModuleName(requiredModule.module()))); + } + + final TreeNode dependencyNode = nodes.get(ModuleUtil.getModuleName( + requiredModule.module())); + + node.addDependsOn(node); + dependencyNode.addDependentModule(node); + } + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/modules/dependencytree/TreeNode.java b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/TreeNode.java new file mode 100644 index 000000000..3a5542624 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/modules/dependencytree/TreeNode.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.libreccm.modules.Module; +import org.libreccm.modules.ModuleUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * + * @author Jens Pelzetter + */ +public final class TreeNode { + + private Module module; + private List dependentModules; + private List dependsOn; + + public TreeNode() { + super(); + + dependentModules = new ArrayList<>(); + dependentModules = new ArrayList<>(); + } + + public TreeNode(final Module module) { + this(); + + this.module = module; + } + + public Module getModule() { + return module; + } + + public void setModule(final Module module) { + this.module = module; + } + + public List getDependentModules() { + return Collections.unmodifiableList(dependentModules); + } + + protected void setDependentModules(final List dependentModules) { + this.dependentModules = dependentModules; + } + + protected void addDependentModule(final TreeNode node) { + dependentModules.add(node); + } + + protected void removeDependentModule(final TreeNode node) { + dependentModules.remove(node); + } + + public List getDependsOn() { + return Collections.unmodifiableList(dependsOn); + } + + protected void setDependsOn(final List dependsOn) { + this.dependsOn = dependsOn; + } + + protected void addDependsOn(final TreeNode node) { + dependsOn.add(node); + } + + protected void removeDependsOn(final TreeNode node) { + dependsOn.remove(node); + } + + @Override + public int hashCode() { + int hash = 5; + + final String moduleName = ModuleUtil.getModuleName(module); + final String version = ModuleUtil.getVersion(module); + + hash = 37 * hash + Objects.hashCode(moduleName); + hash = 37 * hash + Objects.hashCode(version); + + return hash; + } + + @Override + public boolean equals(final Object object) { + if (object == null) { + return false; + } + + if (!(object instanceof TreeNode)) { + return false; + } + + final TreeNode other = (TreeNode) object; + final String name = ModuleUtil.getModuleName(module); + final String otherName = ModuleUtil.getModuleName(other.getModule()); + + if (!name.equals(otherName)) { + return false; + } + + final String version = ModuleUtil.getVersion(module); + final String otherVersion = ModuleUtil.getVersion(other.getModule()); + + return version.equals(otherVersion); + } + +} diff --git a/ccm-core/src/main/resources/META-INF/persistence.xml b/ccm-core/src/main/resources/META-INF/persistence.xml index e85eb1f78..dc0ea24b5 100644 --- a/ccm-core/src/main/resources/META-INF/persistence.xml +++ b/ccm-core/src/main/resources/META-INF/persistence.xml @@ -24,9 +24,18 @@ + + + + diff --git a/ccm-core/src/test/java/org/libreccm/modules/dependencytree/DependencyTreeManagerTest.java b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/DependencyTreeManagerTest.java new file mode 100644 index 000000000..27fb120e8 --- /dev/null +++ b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/DependencyTreeManagerTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import static org.hamcrest.Matchers.*; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage; +import org.junit.After; +import org.junit.AfterClass; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.libreccm.modules.Module; +import org.libreccm.tests.categories.IntegrationTest; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.inject.Instance; +import javax.inject.Inject; + +/** + * + * @author Jens Pelzetter + */ +@Category(IntegrationTest.class) +@RunWith(Arquillian.class) +public class DependencyTreeManagerTest { + + @Inject + @org.libreccm.modules.annotations.Module + private transient Instance modules; + + public DependencyTreeManagerTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Deployment + public static WebArchive createDeployment() { + final PomEquippedResolveStage pom = Maven + .resolver() + .loadPomFromFile("pom.xml"); + final PomEquippedResolveStage dependencies = pom + .importCompileAndRuntimeDependencies(); + final File[] libs = dependencies.resolve().withTransitivity().asFile(); + + for (File lib : libs) { + System.err.printf("Adding file '%s' to test archive...%n", + lib.getName()); + } + + return ShrinkWrap + .create(WebArchive.class, + "LibreCCM-org.libreccm.modules.dependencytree.DependencyTreeManager.war") + .addPackage(DependencyTreeManager.class.getPackage()) + .addPackage(org.libreccm.modules.annotations.Module.class + .getPackage()) + .addPackage(org.libreccm.tests.categories.IntegrationTest.class + .getPackage()) + .addClass(org.libreccm.modules.Module.class) + .addClass(org.libreccm.modules.ModuleUtil.class) + .addAsWebInfResource("test-web.xml", "web.xml") + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); + } + + @Test + @SuppressWarnings("unchecked") + public void allModulesInjected() { + + final List> moduleList = new ArrayList<>(); + for (final Module module : modules) { + moduleList.add((Class) module.getClass()); + } + + assertThat(moduleList.size(), is(4)); + assertThat(moduleList, containsInAnyOrder(TestModuleRoot.class, + TestModuleA.class, + TestModuleB.class, + TestModuleC.class)); + + } + +} diff --git a/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleA.java b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleA.java new file mode 100644 index 000000000..09a007910 --- /dev/null +++ b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleA.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.libreccm.modules.Module; +import org.libreccm.modules.annotations.RequiredModule; + +/** + * + * @author Jens Pelzetter + */ +@org.libreccm.modules.annotations.Module( + name = "org.libreccm.core.ccm-testmodule-a", version = "1.0.0", + requiredModules = { + @RequiredModule(module = TestModuleRoot.class)}) +public class TestModuleA implements Module { + + @Override + public void prepare() { + //Nothing + } + + @Override + public void uninstall() { + //Nothing + } + + @Override + public void init() { + //Nothing + } + + @Override + public void shutdown() { + //Nothing + } + +} diff --git a/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleB.java b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleB.java new file mode 100644 index 000000000..b2fd15e32 --- /dev/null +++ b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleB.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.libreccm.modules.Module; +import org.libreccm.modules.annotations.RequiredModule; + +/** + * + * @author Jens Pelzetter + */ +@org.libreccm.modules.annotations.Module( + name = "org.libreccm.core.ccm-testmodule-a", version = "1.0.0", + requiredModules = { + @RequiredModule(module = TestModuleRoot.class)}) +public class TestModuleB implements Module { + + @Override + public void prepare() { + //Nothing + } + + @Override + public void uninstall() { + //Nothing + } + + @Override + public void init() { + //Nothing + } + + @Override + public void shutdown() { + //Nothing + } + +} diff --git a/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleC.java b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleC.java new file mode 100644 index 000000000..e11ee48b6 --- /dev/null +++ b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleC.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.libreccm.modules.Module; +import org.libreccm.modules.annotations.RequiredModule; + +/** + * + * @author Jens Pelzetter + */ +@org.libreccm.modules.annotations.Module( + name = "org.libreccm.core.ccm-testmodule-a", version = "1.0.0", + requiredModules = { + @RequiredModule(module = TestModuleRoot.class), + @RequiredModule(module = TestModuleA.class)}) +public class TestModuleC implements Module { + + @Override + public void prepare() { + //Nothing + } + + @Override + public void uninstall() { + //Nothing + } + + @Override + public void init() { + //Nothing + } + + @Override + public void shutdown() { + //Nothing + } + +} diff --git a/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleRoot.java b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleRoot.java new file mode 100644 index 000000000..49e7df808 --- /dev/null +++ b/ccm-core/src/test/java/org/libreccm/modules/dependencytree/TestModuleRoot.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.modules.dependencytree; + +import org.libreccm.modules.Module; + +/** + * + * @author Jens Pelzetter + */ +@org.libreccm.modules.annotations.Module( + name = "org.libreccm.core.ccm-testmodule-a", version = "1.0.0") +public class TestModuleRoot implements Module { + + @Override + public void prepare() { + //Nothing + } + + @Override + public void uninstall() { + //Nothing + } + + @Override + public void init() { + //Nothing + } + + @Override + public void shutdown() { + //Nothing + } + +} diff --git a/ccm-core/src/test/resources-tomee-embedded/test-persistence.xml b/ccm-core/src/test/resources-tomee-embedded/test-persistence.xml index df9065f98..5b74c8a71 100644 --- a/ccm-core/src/test/resources-tomee-embedded/test-persistence.xml +++ b/ccm-core/src/test/resources-tomee-embedded/test-persistence.xml @@ -25,6 +25,14 @@ + + + diff --git a/ccm-core/src/test/resources-tomee-remote-pgsql/test-persistence.xml b/ccm-core/src/test/resources-tomee-remote-pgsql/test-persistence.xml index 9a5bee458..5126c7654 100644 --- a/ccm-core/src/test/resources-tomee-remote-pgsql/test-persistence.xml +++ b/ccm-core/src/test/resources-tomee-remote-pgsql/test-persistence.xml @@ -26,6 +26,14 @@ + + + diff --git a/ccm-core/src/test/resources-wildfly8-embedded/test-persistence.xml b/ccm-core/src/test/resources-wildfly8-embedded/test-persistence.xml index b59fd75d3..3912ba83e 100644 --- a/ccm-core/src/test/resources-wildfly8-embedded/test-persistence.xml +++ b/ccm-core/src/test/resources-wildfly8-embedded/test-persistence.xml @@ -26,6 +26,14 @@ + + + diff --git a/ccm-core/src/test/resources-wildfly8-remote-h2-mem/test-persistence.xml b/ccm-core/src/test/resources-wildfly8-remote-h2-mem/test-persistence.xml index 9c65918f0..186fd9255 100644 --- a/ccm-core/src/test/resources-wildfly8-remote-h2-mem/test-persistence.xml +++ b/ccm-core/src/test/resources-wildfly8-remote-h2-mem/test-persistence.xml @@ -26,6 +26,14 @@ + + + diff --git a/ccm-core/src/test/resources-wildfly8-remote-mysql/test-persistence.xml b/ccm-core/src/test/resources-wildfly8-remote-mysql/test-persistence.xml index cc3b2cc77..d7a557597 100644 --- a/ccm-core/src/test/resources-wildfly8-remote-mysql/test-persistence.xml +++ b/ccm-core/src/test/resources-wildfly8-remote-mysql/test-persistence.xml @@ -26,6 +26,14 @@ + + + diff --git a/ccm-core/src/test/resources-wildfly8-remote-pgsql/test-persistence.xml b/ccm-core/src/test/resources-wildfly8-remote-pgsql/test-persistence.xml index 9a5bee458..5126c7654 100644 --- a/ccm-core/src/test/resources-wildfly8-remote-pgsql/test-persistence.xml +++ b/ccm-core/src/test/resources-wildfly8-remote-pgsql/test-persistence.xml @@ -26,6 +26,14 @@ + + +