CCM NG: Code for the module system (not tested yet, also needs some cleanup work)
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3587 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
9ff8ae251b
commit
5eed012faa
|
|
@ -57,6 +57,14 @@
|
||||||
<artifactId>hibernate-validator-cdi</artifactId>
|
<artifactId>hibernate-validator-cdi</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Flyway framework for database schema migrations
|
||||||
|
-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Dependencies for log4j 2 including adapter for the log4j 1.2 API -->
|
<!-- Dependencies for log4j 2 including adapter for the log4j 1.2 API -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_revisions")
|
@Table(name = "ccm_revisions", schema = "ccm_core")
|
||||||
@RevisionEntity()
|
@RevisionEntity()
|
||||||
public class CcmRevision extends DefaultRevisionEntity {
|
public class CcmRevision extends DefaultRevisionEntity {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import javax.persistence.JoinColumn;
|
||||||
* @apiviz.has org.libreccm.core.CcmObject
|
* @apiviz.has org.libreccm.core.CcmObject
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "categorizations")
|
@Table(name = "categorizations", schema = "ccm_core")
|
||||||
public class Categorization implements Serializable {
|
public class Categorization implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 201504301320L;
|
private static final long serialVersionUID = 201504301320L;
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ import javax.validation.constraints.Pattern;
|
||||||
* @apiviz.composedOf org.libreccm.categorization.Categorization
|
* @apiviz.composedOf org.libreccm.categorization.Categorization
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "categories")
|
@Table(name = "categories", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "topLevelCategories",
|
@NamedQuery(name = "topLevelCategories",
|
||||||
query = "SELECT c FROM Category c WHERE c.parentCategory IS NULL")
|
query = "SELECT c FROM Category c WHERE c.parentCategory IS NULL")
|
||||||
|
|
@ -90,7 +90,8 @@ public class Category extends CcmObject implements Serializable {
|
||||||
@Embedded
|
@Embedded
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "category_titles",
|
joinTable = @JoinTable(name = "category_titles",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}
|
@JoinColumn(name = "object_id")}
|
||||||
))
|
))
|
||||||
|
|
@ -103,6 +104,7 @@ public class Category extends CcmObject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "category_descriptions",
|
joinTable = @JoinTable(name = "category_descriptions",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}
|
@JoinColumn(name = "object_id")}
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "category_domains")
|
@Table(name = "category_domains", schema = "ccm_core")
|
||||||
@XmlRootElement(name = "domain", namespace = CAT_XML_NS)
|
@XmlRootElement(name = "domain", namespace = CAT_XML_NS)
|
||||||
public class Domain extends CcmObject implements Serializable {
|
public class Domain extends CcmObject implements Serializable {
|
||||||
|
|
||||||
|
|
@ -114,6 +114,7 @@ public class Domain extends CcmObject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "domain_titles",
|
joinTable = @JoinTable(name = "domain_titles",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}))
|
@JoinColumn(name = "object_id")}))
|
||||||
@XmlElement(name = "title", namespace = CAT_XML_NS)
|
@XmlElement(name = "title", namespace = CAT_XML_NS)
|
||||||
|
|
@ -126,6 +127,7 @@ public class Domain extends CcmObject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "domain_descriptions",
|
joinTable = @JoinTable(name = "domain_descriptions",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}))
|
@JoinColumn(name = "object_id")}))
|
||||||
@XmlElement(name = "description", namespace = CAT_XML_NS)
|
@XmlElement(name = "description", namespace = CAT_XML_NS)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import org.libreccm.web.Application;
|
||||||
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "domain_ownerships")
|
@Table(name = "domain_ownerships", schema = "ccm_core")
|
||||||
public class DomainOwnership implements Serializable {
|
public class DomainOwnership implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 201504301305L;
|
private static final long serialVersionUID = 201504301305L;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import javax.enterprise.inject.spi.CDI;
|
||||||
public class CdiUtil {
|
public class CdiUtil {
|
||||||
|
|
||||||
private final static Logger LOGGER = LogManager.getLogger(CdiUtil.class);
|
private final static Logger LOGGER = LogManager.getLogger(CdiUtil.class);
|
||||||
|
|
||||||
private final transient BeanManager beanManager;
|
private final transient BeanManager beanManager;
|
||||||
|
|
||||||
public CdiUtil() {
|
public CdiUtil() {
|
||||||
|
|
@ -51,8 +51,9 @@ public class CdiUtil {
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Bean<T> bean = (Bean<T>) iterator.next();
|
final Bean<T> bean = (Bean<T>) iterator.next();
|
||||||
final CreationalContext<T> ctx = beanManager.createCreationalContext(bean);
|
final CreationalContext<T> ctx = beanManager
|
||||||
|
.createCreationalContext(bean);
|
||||||
|
|
||||||
return (T) beanManager.getReference(bean, beanType, ctx);
|
return (T) beanManager.getReference(bean, beanType, ctx);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error(new ParameterizedMessage(
|
LOGGER.error(new ParameterizedMessage(
|
||||||
|
|
@ -61,4 +62,5 @@ public class CdiUtil {
|
||||||
"No CDI Bean for type \"%s\" found", beanType.getName()));
|
"No CDI Bean for type \"%s\" found", beanType.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.core;
|
||||||
|
|
||||||
|
import org.libreccm.core.modules.CcmModule;
|
||||||
|
import org.libreccm.core.modules.InitEvent;
|
||||||
|
import org.libreccm.core.modules.InstallEvent;
|
||||||
|
import org.libreccm.core.modules.Module;
|
||||||
|
import org.libreccm.core.modules.ShutdownEvent;
|
||||||
|
import org.libreccm.core.modules.UnInstallEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Module(entities = {org.libreccm.auditing.CcmRevision.class,
|
||||||
|
org.libreccm.categorization.Category.class,
|
||||||
|
org.libreccm.categorization.Categorization.class,
|
||||||
|
org.libreccm.categorization.Domain.class,
|
||||||
|
org.libreccm.categorization.DomainOwnership.class,
|
||||||
|
org.libreccm.core.CcmObject.class,
|
||||||
|
org.libreccm.core.Group.class,
|
||||||
|
org.libreccm.core.GroupMembership.class,
|
||||||
|
org.libreccm.core.Permission.class,
|
||||||
|
org.libreccm.core.Privilege.class,
|
||||||
|
org.libreccm.core.Resource.class,
|
||||||
|
org.libreccm.core.ResourceType.class,
|
||||||
|
org.libreccm.core.Role.class,
|
||||||
|
org.libreccm.core.Subject.class,
|
||||||
|
org.libreccm.core.User.class,
|
||||||
|
org.libreccm.core.modules.InstalledModule.class})
|
||||||
|
public class CcmCore implements CcmModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void install(final InstallEvent event) {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final InitEvent event) {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown(final ShutdownEvent event) {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstall(final UnInstallEvent event) {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_objects")
|
@Table(name = "ccm_objects", schema = "ccm_core")
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
@XmlRootElement(name = "ccm-object", namespace = CORE_XML_NS)
|
@XmlRootElement(name = "ccm-object", namespace = CORE_XML_NS)
|
||||||
//False warning (?). Because this class has been migrated from the old PDL style
|
//False warning (?). Because this class has been migrated from the old PDL style
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ public final class CoreConstants {
|
||||||
|
|
||||||
public static final String CORE_XML_NS = "http://core.libreccm.org";
|
public static final String CORE_XML_NS = "http://core.libreccm.org";
|
||||||
|
|
||||||
|
public static final String DB_SCHEMA = "ccm_core";
|
||||||
|
|
||||||
private CoreConstants() {
|
private CoreConstants() {
|
||||||
//Nothing
|
//Nothing
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_groups")
|
@Table(name = "ccm_groups", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "findGroupByName",
|
@NamedQuery(name = "findGroupByName",
|
||||||
query = "SELECT g FROM Group g WHERE g.name = :groupName")
|
query = "SELECT g FROM Group g WHERE g.name = :groupName")
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ import javax.xml.bind.annotation.XmlTransient;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "group_memberships")
|
@Table(name = "group_memberships", schema = "ccm_core")
|
||||||
@XmlRootElement(name = "group-membership",
|
@XmlRootElement(name = "group-membership",
|
||||||
namespace = CORE_XML_NS)
|
namespace = CORE_XML_NS)
|
||||||
public class GroupMembership implements Serializable {
|
public class GroupMembership implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "permissions")
|
@Table(name = "permissions", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "findPermissionsForSubject",
|
@NamedQuery(name = "findPermissionsForSubject",
|
||||||
query = "SELECT p FROM Permission p WHERE p.grantee = :subject"),
|
query = "SELECT p FROM Permission p WHERE p.grantee = :subject"),
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_privileges")
|
@Table(name = "ccm_privileges", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "findPrivilegeByName",
|
@NamedQuery(name = "findPrivilegeByName",
|
||||||
query = "SELECT p FROM Privilege p "
|
query = "SELECT p FROM Privilege p "
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ import javax.persistence.TemporalType;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "resources")
|
@Table(name = "resources", schema = "ccm_core")
|
||||||
public class Resource extends CcmObject implements Serializable {
|
public class Resource extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 7345482620613842781L;
|
private static final long serialVersionUID = 7345482620613842781L;
|
||||||
|
|
@ -65,6 +65,7 @@ public class Resource extends CcmObject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "resource_titles",
|
joinTable = @JoinTable(name = "resource_titles",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}))
|
@JoinColumn(name = "object_id")}))
|
||||||
private LocalizedString title;
|
private LocalizedString title;
|
||||||
|
|
@ -76,6 +77,7 @@ public class Resource extends CcmObject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "resource_descriptions",
|
joinTable = @JoinTable(name = "resource_descriptions",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "object_id")}))
|
@JoinColumn(name = "object_id")}))
|
||||||
private LocalizedString description;
|
private LocalizedString description;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import org.libreccm.l10n.LocalizedString;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "resource_types")
|
@Table(name = "resource_types", schema = "ccm_core")
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
@ -59,6 +59,7 @@ public class ResourceType implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
joinTable = @JoinTable(name = "resource_type_descriptions",
|
joinTable = @JoinTable(name = "resource_type_descriptions",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "resource_type_id")}))
|
@JoinColumn(name = "resource_type_id")}))
|
||||||
private LocalizedString description;
|
private LocalizedString description;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import javax.persistence.NamedQuery;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_roles")
|
@Table(name = "ccm_roles", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "findRolesForName",
|
@NamedQuery(name = "findRolesForName",
|
||||||
query = "SELECT r FROM Role r "
|
query = "SELECT r FROM Role r "
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "subjects")
|
@Table(name = "subjects", schema = "ccm_core")
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
@XmlRootElement(name = "subject", namespace = CORE_XML_NS)
|
@XmlRootElement(name = "subject", namespace = CORE_XML_NS)
|
||||||
public class Subject implements Serializable {
|
public class Subject implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ import javax.xml.bind.annotation.XmlTransient;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "ccm_users")
|
@Table(name = "ccm_users", schema = "ccm_core")
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "findUserByScreenName",
|
@NamedQuery(name = "findUserByScreenName",
|
||||||
query = "SELECT u FROM User u WHERE u.screenName = :screenname"),
|
query = "SELECT u FROM User u WHERE u.screenName = :screenname"),
|
||||||
|
|
@ -83,6 +83,7 @@ public class User extends Subject implements Serializable {
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "user_names",
|
name = "user_names",
|
||||||
joinTable = @JoinTable(name = "user_names",
|
joinTable = @JoinTable(name = "user_names",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = " user_id")}))
|
@JoinColumn(name = " user_id")}))
|
||||||
@XmlElement(name = "person-name", namespace = CORE_XML_NS)
|
@XmlElement(name = "person-name", namespace = CORE_XML_NS)
|
||||||
|
|
@ -102,6 +103,7 @@ public class User extends Subject implements Serializable {
|
||||||
|
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
@CollectionTable(name = "user_email_addresses",
|
@CollectionTable(name = "user_email_addresses",
|
||||||
|
schema = "ccm_core",
|
||||||
joinColumns = {
|
joinColumns = {
|
||||||
@JoinColumn(name = "user_id")})
|
@JoinColumn(name = "user_id")})
|
||||||
@Size(min = 1)
|
@Size(min = 1)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.flywaydb.core.api.MigrationInfo;
|
||||||
|
import org.flywaydb.core.internal.util.jdbc.JdbcUtils;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
|
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||||
|
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class CcmIntegrator implements Integrator {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
CcmIntegrator.class);
|
||||||
|
|
||||||
|
private ServiceLoader<CcmModule> modules;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(final Configuration configuration,
|
||||||
|
final SessionFactoryImplementor sessionFactory,
|
||||||
|
final SessionFactoryServiceRegistry registry) {
|
||||||
|
LOGGER.info("Retrieving modules...");
|
||||||
|
modules = ServiceLoader.load(CcmModule.class);
|
||||||
|
for (final CcmModule module : modules) {
|
||||||
|
LOGGER.info("Found module class {}...", module.getClass().getName());
|
||||||
|
final ModuleInfo moduleInfo = new ModuleInfo();
|
||||||
|
moduleInfo.load(module);
|
||||||
|
LOGGER.info("Found module {}.", moduleInfo.getModuleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection connection = null;
|
||||||
|
try {
|
||||||
|
final DependencyTreeManager treeManager
|
||||||
|
= new DependencyTreeManager();
|
||||||
|
final List<TreeNode> tree = treeManager.generateTree(modules);
|
||||||
|
final List<TreeNode> orderedNodes = treeManager.orderModules(tree);
|
||||||
|
|
||||||
|
final DataSource dataSource = (DataSource) sessionFactory.
|
||||||
|
getProperties().get("javax.persistence.jtaDataSource");
|
||||||
|
connection = dataSource.getConnection();
|
||||||
|
|
||||||
|
for (final TreeNode node : orderedNodes) {
|
||||||
|
migrateModule(node.getModule().getClass(), dataSource);
|
||||||
|
|
||||||
|
for (Class<?> entity : node.getModuleInfo().getModuleEntities()) {
|
||||||
|
configuration.addAnnotatedClass(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (DependencyException | SQLException ex) {
|
||||||
|
throw new IntegrationException("Failed to integrate modules", ex);
|
||||||
|
} finally {
|
||||||
|
JdbcUtils.closeConnection(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("All modules integrated successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSchemaName(final ModuleInfo moduleInfo) {
|
||||||
|
return moduleInfo.getModuleName().toLowerCase().replace("-", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLocation(final ModuleInfo moduleInfo,
|
||||||
|
final Connection connection) throws SQLException {
|
||||||
|
final StringBuffer buffer = new StringBuffer(
|
||||||
|
"classpath:/db/migrations/");
|
||||||
|
//buffer.append(ModuleUtil.getModulePackageName(module));
|
||||||
|
buffer.append(moduleInfo.getModuleDataPackage());
|
||||||
|
switch (connection.getMetaData().getDatabaseProductName()) {
|
||||||
|
case "MySQL":
|
||||||
|
buffer.append("/mysql");
|
||||||
|
break;
|
||||||
|
case "PostgreSQL":
|
||||||
|
buffer.append("/pgsql");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IntegrationException(String.format(
|
||||||
|
"Integration failed. Database \"%s\" is not supported yet.",
|
||||||
|
connection.getMetaData().
|
||||||
|
getDatabaseProductName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void migrateModule(final Class<? extends CcmModule> module,
|
||||||
|
final DataSource dataSource) throws SQLException {
|
||||||
|
final Connection connection = dataSource.getConnection();
|
||||||
|
|
||||||
|
final ModuleInfo moduleInfo = new ModuleInfo();
|
||||||
|
moduleInfo.load(module);
|
||||||
|
|
||||||
|
final Flyway flyway = new Flyway();
|
||||||
|
flyway.setDataSource(dataSource);
|
||||||
|
flyway.setSchemas(getSchemaName(moduleInfo));
|
||||||
|
flyway.setLocations(getLocation(moduleInfo, connection));
|
||||||
|
|
||||||
|
final MigrationInfo current = flyway.info().current();
|
||||||
|
boolean newModule;
|
||||||
|
if (current == null) {
|
||||||
|
LOGGER.info("No version, database schema is considered empty.");
|
||||||
|
newModule = true;
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Current version of schema {} in database is {}",
|
||||||
|
getSchemaName(moduleInfo),
|
||||||
|
current.getVersion());
|
||||||
|
newModule = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
flyway.migrate();
|
||||||
|
|
||||||
|
LOGGER.info("Migrated schema {} in database to version {}",
|
||||||
|
getSchemaName(moduleInfo),
|
||||||
|
flyway.info().current().getVersion());
|
||||||
|
|
||||||
|
if (newModule) {
|
||||||
|
final Statement statement = connection.createStatement();
|
||||||
|
statement.execute(String.format(
|
||||||
|
"INSERT INTO flyhydra_core.installed_modules "
|
||||||
|
+ "(module_class_name, status) "
|
||||||
|
+ "VALUES ('%s', 'NEW')",
|
||||||
|
module.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void integrate(final MetadataImplementor metadata,
|
||||||
|
final SessionFactoryImplementor sessionFactory,
|
||||||
|
final SessionFactoryServiceRegistry registry) {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disintegrate(final SessionFactoryImplementor sessionFactory,
|
||||||
|
final SessionFactoryServiceRegistry registry) {
|
||||||
|
LOGGER.info("Hibernate desintegrating...");
|
||||||
|
|
||||||
|
Connection connection = null;
|
||||||
|
LOGGER.info("Removing schemas for modules scheduled for uninstall...");
|
||||||
|
try {
|
||||||
|
|
||||||
|
final DataSource dataSource = (DataSource) sessionFactory
|
||||||
|
.getProperties().get("javax.persistence.jtaDataSource");
|
||||||
|
connection = dataSource.getConnection();
|
||||||
|
System.out.println("checking modules...");
|
||||||
|
LOGGER.info("Checking modules...");
|
||||||
|
|
||||||
|
for (final CcmModule module : modules) {
|
||||||
|
final ModuleInfo moduleInfo = new ModuleInfo();
|
||||||
|
moduleInfo.load(module);
|
||||||
|
|
||||||
|
final Statement query = connection.createStatement();
|
||||||
|
final ResultSet result = query.executeQuery(
|
||||||
|
String.format("SELECT module_class_name, status "
|
||||||
|
+ "FROM flyhydra_core.installed_modules "
|
||||||
|
+ "WHERE module_class_name = '%s'",
|
||||||
|
module.getClass().getName()));
|
||||||
|
System.out.printf("Checking status of module %s...\n",
|
||||||
|
module.getClass().getName());
|
||||||
|
|
||||||
|
if (result.next() && ModuleStatus.UNINSTALL.toString().equals(
|
||||||
|
result.getString("status"))) {
|
||||||
|
|
||||||
|
LOGGER.info("Removing schema for module %s...",
|
||||||
|
module.getClass().getName());
|
||||||
|
final Flyway flyway = new Flyway();
|
||||||
|
flyway.setDataSource(dataSource);
|
||||||
|
flyway.setSchemas(getSchemaName(moduleInfo));
|
||||||
|
flyway.setLocations(getLocation(moduleInfo, connection));
|
||||||
|
LOGGER.warn("Deleting schema for module {}...",
|
||||||
|
moduleInfo.getModuleName());
|
||||||
|
flyway.clean();
|
||||||
|
|
||||||
|
final Statement statement = connection.createStatement();
|
||||||
|
statement.addBatch(String.format(
|
||||||
|
"DELETE FROM flyhydra_core.installed_modules "
|
||||||
|
+ "WHERE module_class_name = '%s'",
|
||||||
|
module.getClass().getName()));
|
||||||
|
statement.executeBatch();
|
||||||
|
LOGGER.info("Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
LOGGER.error("Desintegration failed: ", ex);
|
||||||
|
System.err.println("Desintration failed");
|
||||||
|
ex.printStackTrace(System.err);
|
||||||
|
System.err.println();
|
||||||
|
SQLException next = ex.getNextException();
|
||||||
|
while(next != null) {
|
||||||
|
next.printStackTrace(System.err);
|
||||||
|
System.err.println();
|
||||||
|
next = next.getNextException();
|
||||||
|
}
|
||||||
|
throw new IntegrationException("Failed to desintegrate.", next);
|
||||||
|
} finally {
|
||||||
|
JdbcUtils.closeConnection(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.core.modules;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import org.libreccm.modules.ModuleManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface is implemented by all CCM module classes. It defines several
|
||||||
|
* methods which an be used by a module the execute code when the module is
|
||||||
|
* installed, initialised, shutdown or uninstalled. If a module does not need
|
||||||
|
* one of the methods defined by this interface the implementation can simply be
|
||||||
|
* left empty. The link {@link ModuleManager} provides each method with an
|
||||||
|
* event object which provides access to the {@link EntityManager}.
|
||||||
|
*
|
||||||
|
* A module may also needs some metadata which is provided by the {@link Module}
|
||||||
|
* annotation.
|
||||||
|
*
|
||||||
|
* When installing a module please refer also to the
|
||||||
|
* <a href="../../../../../../module-system.html">modules pages</a> in the CCM
|
||||||
|
* documentation.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public interface CcmModule {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of this method is called after the module is installed.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
void install(InstallEvent event);
|
||||||
|
|
||||||
|
void init(InitEvent event);
|
||||||
|
|
||||||
|
void shutdown(ShutdownEvent event);
|
||||||
|
|
||||||
|
void uninstall(UnInstallEvent event);
|
||||||
|
}
|
||||||
|
|
@ -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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class DependencyException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 10938361383494729L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>DependencyException</code> without detail
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
public DependencyException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>DependencyException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param msg the detail message.
|
||||||
|
*/
|
||||||
|
public DependencyException(final String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>DependencyException</code> which wraps
|
||||||
|
* the specified exception.
|
||||||
|
*
|
||||||
|
* @param exception The exception to wrap.
|
||||||
|
*/
|
||||||
|
public DependencyException(final Exception exception) {
|
||||||
|
super(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>DependencyException</code> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.maven.artifact.versioning.ComparableVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements topological sorting to determine the order in which the
|
||||||
|
* modules are loaded and initialised.
|
||||||
|
*
|
||||||
|
* The class is used by creating an instance with the parameterless constructor.
|
||||||
|
* To create the tree/graph call the
|
||||||
|
* {@link #generateTree(javax.enterprise.inject.Instance)} method. With the
|
||||||
|
* returned list of nodes call the the {@link #orderModules(java.util.List)}
|
||||||
|
* method. The list returned by {@link #orderModules(java.util.List)} contains
|
||||||
|
* all modules in order.
|
||||||
|
*
|
||||||
|
* More information about topological sorting:
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/Topological_sorting">https://en.wikipedia.org/wiki/Topological_sorting</a>
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
final class DependencyTreeManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
DependencyTreeManager.class);
|
||||||
|
|
||||||
|
public List<TreeNode> generateTree(final Iterable<CcmModule> modules)
|
||||||
|
throws DependencyException {
|
||||||
|
|
||||||
|
LOGGER.info("Starting to generate dependency tree...");
|
||||||
|
|
||||||
|
final Map<String, TreeNode> nodes = new HashMap<>();
|
||||||
|
|
||||||
|
for (final CcmModule module : modules) {
|
||||||
|
createTreeNode(module, nodes);
|
||||||
|
}
|
||||||
|
final List<TreeNode> nodeList = new ArrayList<>();
|
||||||
|
for (final Map.Entry<String, TreeNode> entry : nodes.entrySet()) {
|
||||||
|
nodeList.add(entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Dependency tree generated.");
|
||||||
|
|
||||||
|
return nodeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TreeNode> orderModules(final List<TreeNode> dependencyTree)
|
||||||
|
throws DependencyException {
|
||||||
|
LOGGER.info("Creating an ordered list from the dependency tree...");
|
||||||
|
|
||||||
|
final List<TreeNode> orderedModules = new ArrayList<>();
|
||||||
|
final List<TreeNode> 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()));
|
||||||
|
LOGGER.info(
|
||||||
|
"\tModule \"{}\" does not depend on any other module",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
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()));
|
||||||
|
LOGGER.info("\tProcessing node for module \"{}\"...",
|
||||||
|
current.getModuleInfo().getModuleName());
|
||||||
|
|
||||||
|
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()));
|
||||||
|
LOGGER.info("\t{}", node.getModuleInfo().getModuleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 CcmModule module,
|
||||||
|
final Map<String, TreeNode> nodes) {
|
||||||
|
final TreeNode node = new TreeNode(module);
|
||||||
|
|
||||||
|
// LOGGER.info("Creating node for module \"{}\"...",
|
||||||
|
// ModuleUtil.getModuleName(module));
|
||||||
|
LOGGER.info("Creating node for module \"{}\"...",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
// nodes.put(ModuleUtil.getModuleName(module), node);
|
||||||
|
nodes.put(node.getModuleInfo().getModuleName(), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDependencyRelations(final CcmModule module,
|
||||||
|
final Map<String, TreeNode> nodes)
|
||||||
|
throws DependencyException {
|
||||||
|
final ModuleInfo moduleInfo = new ModuleInfo();
|
||||||
|
moduleInfo.load(module);
|
||||||
|
|
||||||
|
// LOGGER.info("Adding dependency relations for module \"{}\"...",
|
||||||
|
// ModuleUtil.getModuleName(module));
|
||||||
|
LOGGER.info("Adding dependency relations for module \"{}\"...",
|
||||||
|
moduleInfo.getModuleName());
|
||||||
|
|
||||||
|
//final String moduleName = ModuleUtil.getModuleName(module)
|
||||||
|
final String moduleName = moduleInfo.getModuleName();
|
||||||
|
|
||||||
|
if (!nodes.containsKey(moduleName)) {
|
||||||
|
// LOGGER.fatal("Modules nodes map does contain an entry for \"{}\". "
|
||||||
|
// + "That should not happen.",
|
||||||
|
// ModuleUtil.getModuleName(module));
|
||||||
|
LOGGER.fatal("Modules nodes map does contain an entry for \"{}\". "
|
||||||
|
+ "That should not happen.",
|
||||||
|
moduleInfo.getModuleName());
|
||||||
|
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));
|
||||||
|
LOGGER.info("Processing required modules for module \"{}\"...",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
// for (final RequiredModule requiredModule : ModuleUtil
|
||||||
|
// .getRequiredModules(
|
||||||
|
// module)) {
|
||||||
|
for (final RequiredModule requiredModule : node.getModuleInfo().
|
||||||
|
getRequiredModules()) {
|
||||||
|
|
||||||
|
final ModuleInfo requiredModuleInfo = new ModuleInfo();
|
||||||
|
requiredModuleInfo.load(requiredModule.module());
|
||||||
|
|
||||||
|
// LOGGER.info("\tModule \"{}\" requires module \"{}\".",
|
||||||
|
// ModuleUtil.getModuleName(module),
|
||||||
|
// ModuleUtil.getModuleName(requiredModule.module()));
|
||||||
|
LOGGER.info("\tModule \"{}\" requires module \"{}\".",
|
||||||
|
node.getModuleInfo().getModuleName(),
|
||||||
|
requiredModuleInfo.getModuleName());
|
||||||
|
|
||||||
|
// if (!nodes.containsKey(ModuleUtil.getModuleName(requiredModule
|
||||||
|
// .module()))) {
|
||||||
|
if (!nodes.containsKey(requiredModuleInfo.getModuleName())) {
|
||||||
|
|
||||||
|
LOGGER.fatal("Required module \"{}\" no found.",
|
||||||
|
requiredModuleInfo.getModuleName());
|
||||||
|
|
||||||
|
throw new DependencyException(String.format(
|
||||||
|
"Module \"%s\" depends on module \"%s\" but the dependency "
|
||||||
|
+ "tree does contain an entry for module \"%s\".",
|
||||||
|
moduleInfo.getModuleName(),
|
||||||
|
requiredModuleInfo.getModuleName(),
|
||||||
|
requiredModuleInfo.getModuleName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// final TreeNode dependencyNode = nodes.get(ModuleUtil.getModuleName(
|
||||||
|
// requiredModule.module()));
|
||||||
|
final TreeNode dependencyNode = nodes.get(requiredModuleInfo.
|
||||||
|
getModuleName());
|
||||||
|
|
||||||
|
//Check version
|
||||||
|
// if (!validateVersion(ModuleUtil.getVersion(dependencyNode
|
||||||
|
// .getModule()),
|
||||||
|
if (!validateVersion(dependencyNode.getModuleInfo().
|
||||||
|
getModuleVersion(),
|
||||||
|
requiredModule.minVersion(),
|
||||||
|
requiredModule.maxVersion())) {
|
||||||
|
throw new DependencyException(String.format(
|
||||||
|
"The required module is avialable but in the correct "
|
||||||
|
+ "version. "
|
||||||
|
+ "Available version: \"%s\"; "
|
||||||
|
+ "minimal required version: \"%s\"; "
|
||||||
|
+ "maximum required version: \"%s\"",
|
||||||
|
dependencyNode.getModuleInfo().getModuleVersion(),
|
||||||
|
requiredModule.minVersion(),
|
||||||
|
requiredModule.maxVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
node.addDependsOn(dependencyNode);
|
||||||
|
dependencyNode.addDependentModule(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for checking if an dependency is available in the required
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* @param availableVersion The available version. Can't be {@code null} or
|
||||||
|
* empty.
|
||||||
|
* @param minRequiredVersion The minimal version required. Can be
|
||||||
|
* {@code null} or empty.
|
||||||
|
* @param maxRequiredVersion The maximum version required. Can be
|
||||||
|
* {@code null} or empty.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the available version is in the required range,
|
||||||
|
* {@code false} if not.
|
||||||
|
*/
|
||||||
|
//The names are fine. Shorter names would be less readable. Also removing
|
||||||
|
//the parentheses in the ifs would make the conditions less readable.
|
||||||
|
@SuppressWarnings({"PMD.LongVariable",
|
||||||
|
"PMD.UselessParentheses",
|
||||||
|
"PMD.CyclomaticComplexity"})
|
||||||
|
private boolean validateVersion(final String availableVersion,
|
||||||
|
final String minRequiredVersion,
|
||||||
|
final String maxRequiredVersion) {
|
||||||
|
if (availableVersion == null || availableVersion.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("No available version specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
||||||
|
&& (maxRequiredVersion == null || maxRequiredVersion.
|
||||||
|
isEmpty())) {
|
||||||
|
return true;
|
||||||
|
} else if ((minRequiredVersion != null && !minRequiredVersion.isEmpty())
|
||||||
|
&& (maxRequiredVersion == null || maxRequiredVersion
|
||||||
|
.isEmpty())) {
|
||||||
|
final ComparableVersion minVersion = new ComparableVersion(
|
||||||
|
minRequiredVersion);
|
||||||
|
final ComparableVersion version = new ComparableVersion(
|
||||||
|
availableVersion);
|
||||||
|
|
||||||
|
return minVersion.compareTo(version) <= 0;
|
||||||
|
} else if ((minRequiredVersion == null || minRequiredVersion.isEmpty())
|
||||||
|
&& (maxRequiredVersion != null && !maxRequiredVersion
|
||||||
|
.isEmpty())) {
|
||||||
|
final ComparableVersion maxVersion = new ComparableVersion(
|
||||||
|
maxRequiredVersion);
|
||||||
|
final ComparableVersion version = new ComparableVersion(
|
||||||
|
availableVersion);
|
||||||
|
|
||||||
|
return version.compareTo(maxVersion) <= 0;
|
||||||
|
} else {
|
||||||
|
final ComparableVersion minVersion = new ComparableVersion(
|
||||||
|
minRequiredVersion);
|
||||||
|
final ComparableVersion maxVersion = new ComparableVersion(
|
||||||
|
(maxRequiredVersion));
|
||||||
|
final ComparableVersion version = new ComparableVersion(
|
||||||
|
availableVersion);
|
||||||
|
return minVersion.compareTo(version) <= 0 && version.compareTo(
|
||||||
|
maxVersion) <= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class InitEvent extends ModuleEvent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class InstallEvent extends ModuleEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "installed_modules", schema = DB_SCHEMA)
|
||||||
|
public class InstalledModule implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6240025652113643164L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "module_class_name", length = 2048)
|
||||||
|
private String moduleClassName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private ModuleStatus status;
|
||||||
|
|
||||||
|
public String getModuleClassName() {
|
||||||
|
return moduleClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModuleClassName(String moduleClassName) {
|
||||||
|
this.moduleClassName = moduleClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(ModuleStatus status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
hash = 79 * hash + Objects.hashCode(moduleClassName);
|
||||||
|
hash = 79 * hash + Objects.hashCode(status);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final InstalledModule other = (InstalledModule) obj;
|
||||||
|
if (!Objects.equals(moduleClassName, other.getModuleClassName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return status == other.getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canEqual(final Object obj) {
|
||||||
|
return obj instanceof InstalledModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toString("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(final String data) {
|
||||||
|
return String.format(
|
||||||
|
"%s{ "
|
||||||
|
+ "moduleClassName = \"%s\"; "
|
||||||
|
+ "status = %s"
|
||||||
|
+ "%s"
|
||||||
|
+ " }",
|
||||||
|
super.toString(),
|
||||||
|
moduleClassName,
|
||||||
|
status.toString(),
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class IntegrationException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8505205543077310805L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>IntegrationException</code> without
|
||||||
|
* detail message.
|
||||||
|
*/
|
||||||
|
public IntegrationException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>IntegrationException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param msg the detail message.
|
||||||
|
*/
|
||||||
|
public IntegrationException(final String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegrationException(final Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntegrationException(final String msg, final Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.*;
|
||||||
|
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation for describing some meta of a module.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Target({TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Module {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the module, overriding the name provided by the pom.xml and the
|
||||||
|
* module info file of the module.
|
||||||
|
*
|
||||||
|
* @return The name of the module, overriding the value provided by the
|
||||||
|
* module-info file.
|
||||||
|
*/
|
||||||
|
String name() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package name of resources of the package like DB migrations, overriding
|
||||||
|
* default value constructed from the group id and the artifact id of the
|
||||||
|
* module.
|
||||||
|
*
|
||||||
|
* @return The package name for resources of the module.
|
||||||
|
*/
|
||||||
|
String packageName() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of module, overriding the value provided by the module info
|
||||||
|
* file of the module.
|
||||||
|
*
|
||||||
|
* @return The version of the module.
|
||||||
|
*/
|
||||||
|
String version() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modules required by the annotated module.
|
||||||
|
*
|
||||||
|
* @return An array of the dependencies of the module.
|
||||||
|
*/
|
||||||
|
RequiredModule[] requiredModules() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JPA entities provided by the annotated module.
|
||||||
|
*
|
||||||
|
* @return An array with the JPA entity classes of the annotated module.
|
||||||
|
*/
|
||||||
|
Class<?>[] entities() default {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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.core.modules;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class ModuleEvent {
|
||||||
|
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
ModuleEvent() {
|
||||||
|
//Nothing for now
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleEvent(final EntityManager entityManager) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityManager getEntityManager() {
|
||||||
|
return entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityManager(final EntityManager entityManager) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLDataException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ModuleInfo {
|
||||||
|
|
||||||
|
private static final String ARTIFACT_ID = "artifactId";
|
||||||
|
private static final String GROUP_ID = "groupId";
|
||||||
|
private static final String VERSION = "version";
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(ModuleInfo.class);
|
||||||
|
|
||||||
|
private String moduleName;
|
||||||
|
private String moduleDataPackage;
|
||||||
|
private Class<?>[] moduleEntities;
|
||||||
|
private String moduleVersion;
|
||||||
|
private RequiredModule[] requiredModules;
|
||||||
|
|
||||||
|
public ModuleInfo() {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModuleName() {
|
||||||
|
return moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModuleDataPackage() {
|
||||||
|
return moduleDataPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDbSchemaName() {
|
||||||
|
return moduleName.toLowerCase(Locale.ROOT).replace("-", "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDbScriptsLocation(final Connection connection)
|
||||||
|
throws SQLException {
|
||||||
|
final StringBuffer buffer = new StringBuffer("classpath:/db/migrations/");
|
||||||
|
buffer.append(moduleDataPackage);
|
||||||
|
switch (connection.getMetaData().getDatabaseProductName()) {
|
||||||
|
case "H2": {
|
||||||
|
buffer.append("/h2");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "MySQL":
|
||||||
|
buffer.append("/mysql");
|
||||||
|
break;
|
||||||
|
case "PostgreSQL":
|
||||||
|
buffer.append("/postgresql");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IntegrationException(String.format(
|
||||||
|
"Integration failed. Database \"%s\" is not supported yet.",
|
||||||
|
connection.getMetaData().
|
||||||
|
getDatabaseProductName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModuleVersion() {
|
||||||
|
return moduleVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getModuleEntities() {
|
||||||
|
return Collections.unmodifiableList(Arrays.asList(moduleEntities));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RequiredModule> getRequiredModules() {
|
||||||
|
return Collections.unmodifiableList(Arrays.asList(requiredModules));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(final CcmModule module) {
|
||||||
|
load(module.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(final Class<? extends CcmModule> moduleClass) {
|
||||||
|
LOGGER.info("Reading module info for {}...", moduleClass.getName());
|
||||||
|
final Module annotation = moduleClass.getAnnotation(Module.class);
|
||||||
|
final Properties properties = new Properties();
|
||||||
|
|
||||||
|
final String path = String.format("/module-info/%s.properties",
|
||||||
|
moduleClass.getName());
|
||||||
|
LOGGER.info("Trying to retrieve module info for module {} from {}...",
|
||||||
|
moduleClass.getName(),
|
||||||
|
path);
|
||||||
|
final InputStream stream = moduleClass.getResourceAsStream(path);
|
||||||
|
if (stream == null) {
|
||||||
|
LOGGER.warn("No module info for {} found at {}",
|
||||||
|
moduleClass.getName(),
|
||||||
|
path);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
properties.load(stream);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error("Failed to read module info for {} at {}.",
|
||||||
|
moduleClass.getName(),
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("Reading module name...");
|
||||||
|
if (annotation.name() != null && !annotation.name().isEmpty()) {
|
||||||
|
moduleName = annotation.name();
|
||||||
|
} else if (properties.getProperty(ARTIFACT_ID) != null
|
||||||
|
&& !properties.getProperty(ARTIFACT_ID).isEmpty()) {
|
||||||
|
moduleName = properties.getProperty(ARTIFACT_ID);
|
||||||
|
} else {
|
||||||
|
LOGGER.warn(
|
||||||
|
"The module was not specificied by the module annotation "
|
||||||
|
+ "or by the module info file. Creating name from "
|
||||||
|
+ "simple name of the module class.");
|
||||||
|
moduleName = moduleClass.getSimpleName().toLowerCase();
|
||||||
|
}
|
||||||
|
LOGGER.info("Module name is \"{}\".", moduleName);
|
||||||
|
|
||||||
|
LOGGER.info("Reading module package name...");
|
||||||
|
if (annotation.packageName() != null
|
||||||
|
&& !annotation.packageName().isEmpty()) {
|
||||||
|
moduleDataPackage = annotation.packageName();
|
||||||
|
} else if (properties.getProperty(GROUP_ID) != null
|
||||||
|
&& !properties.getProperty(GROUP_ID).isEmpty()) {
|
||||||
|
moduleDataPackage = String.format("%s/%s",
|
||||||
|
properties.getProperty(GROUP_ID),
|
||||||
|
properties.
|
||||||
|
getProperty(ARTIFACT_ID).replace(
|
||||||
|
"-", "_"));
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("The module data package was specified by the module "
|
||||||
|
+ "annotation nore was an group id found in the module info"
|
||||||
|
+ "file. Creating data package name from the name of the "
|
||||||
|
+ "module class.");
|
||||||
|
moduleDataPackage = moduleClass.getName().toLowerCase();
|
||||||
|
}
|
||||||
|
LOGGER.info("Module data package is \"{}\".", moduleDataPackage);
|
||||||
|
|
||||||
|
if (annotation.version() != null && !annotation.version().isEmpty()) {
|
||||||
|
moduleVersion = annotation.version();
|
||||||
|
} else if (properties.getProperty(VERSION) != null
|
||||||
|
&& !properties.getProperty(VERSION).isEmpty()) {
|
||||||
|
moduleVersion = properties.getProperty(VERSION);
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Module version is not specified by the module "
|
||||||
|
+ "annotation or in the module info file. Module version is "
|
||||||
|
+ "undefinied. This can lead to all sorts of strange errors!");
|
||||||
|
}
|
||||||
|
LOGGER.info("Module version is \"{}.\"", moduleVersion);
|
||||||
|
|
||||||
|
requiredModules = annotation.requiredModules();
|
||||||
|
moduleEntities = annotation.entities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ModuleManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
ModuleManager.class
|
||||||
|
);
|
||||||
|
|
||||||
|
@PersistenceContext(name = "FlyHydra")
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
private List<TreeNode> moduleNodes;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void initDependencyTree() {
|
||||||
|
LOGGER.info("Finding modules");
|
||||||
|
final ServiceLoader<CcmModule> modules = ServiceLoader.load(
|
||||||
|
CcmModule.class);
|
||||||
|
|
||||||
|
LOGGER.info("Creating dependency tree these modules:");
|
||||||
|
for (final CcmModule module : modules) {
|
||||||
|
final ModuleInfo moduleInfo = new ModuleInfo();
|
||||||
|
moduleInfo.load(module);
|
||||||
|
LOGGER.info("\t{} {}",
|
||||||
|
// ModuleUtil.getModuleName(module),
|
||||||
|
// ModuleUtil.getVersion(module));
|
||||||
|
moduleInfo.getModuleName(),
|
||||||
|
moduleInfo.getModuleVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
final DependencyTreeManager treeManager = new DependencyTreeManager();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final List<TreeNode> tree = treeManager.generateTree(modules);
|
||||||
|
moduleNodes = treeManager.orderModules(tree);
|
||||||
|
} catch (DependencyException ex) {
|
||||||
|
throw new ModuleManagerException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void initModules() {
|
||||||
|
LOGGER.info("Initalising modules...");
|
||||||
|
for (final TreeNode node : moduleNodes) {
|
||||||
|
final InstallEvent installEvent = new InstallEvent();
|
||||||
|
installEvent.setEntityManager(entityManager);
|
||||||
|
|
||||||
|
final InstalledModule installedModule = entityManager.find(
|
||||||
|
InstalledModule.class, node.getModule().getClass().getName());
|
||||||
|
if (installedModule != null
|
||||||
|
&& installedModule.getStatus() == ModuleStatus.NEW) {
|
||||||
|
node.getModule().install(installEvent);
|
||||||
|
installedModule.setStatus(ModuleStatus.INSTALLED);
|
||||||
|
entityManager.merge(installedModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
final InitEvent initEvent = new InitEvent();
|
||||||
|
initEvent.setEntityManager(entityManager);
|
||||||
|
node.getModule().init(initEvent);
|
||||||
|
|
||||||
|
LOGGER.info("Data from module-info.properties for {}:",
|
||||||
|
node.getModule().getClass().getName());
|
||||||
|
final Properties moduleInfo = getModuleInfo(node.getModule());
|
||||||
|
LOGGER
|
||||||
|
.info("Module group id: {}", moduleInfo.getProperty(
|
||||||
|
"groupId"));
|
||||||
|
LOGGER.info("Module artifact id: {}", moduleInfo.getProperty(
|
||||||
|
"artifactId"));
|
||||||
|
LOGGER.info("Module version: {}", moduleInfo.getProperty("version"));
|
||||||
|
|
||||||
|
LOGGER.info("Module build date: {}", moduleInfo.getProperty(
|
||||||
|
"build.date"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getModuleInfo(final CcmModule module) {
|
||||||
|
final Properties moduleInfo = new Properties();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// final String moduleInfoPath = String.format("/%s/module-info.properties",
|
||||||
|
// module.getClass().getName().replace(".", "/"));
|
||||||
|
final String moduleInfoPath = String.format(
|
||||||
|
"/module-info/%s.properties",
|
||||||
|
module.getClass().getName());
|
||||||
|
LOGGER.info("Path for module info: {}", moduleInfoPath);
|
||||||
|
final InputStream stream = module.getClass().getResourceAsStream(
|
||||||
|
moduleInfoPath);
|
||||||
|
if (stream == null) {
|
||||||
|
LOGGER.warn("No module info found.");
|
||||||
|
} else {
|
||||||
|
moduleInfo.load(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error("Failed to read module-info.properties for module {}.",
|
||||||
|
module.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return moduleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void shutdownModules() {
|
||||||
|
LOGGER.info("Shutting down modules...");
|
||||||
|
System.out.println("Shutting down modules...");
|
||||||
|
for (final TreeNode node : moduleNodes) {
|
||||||
|
final ShutdownEvent shutdownEvent = new ShutdownEvent();
|
||||||
|
shutdownEvent.setEntityManager(entityManager);
|
||||||
|
|
||||||
|
node.getModule().shutdown(shutdownEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Modules shut down.");
|
||||||
|
|
||||||
|
System.out.println("Checking for modules to uninstall...");
|
||||||
|
for (final TreeNode node : moduleNodes) {
|
||||||
|
System.out.printf("Checking status of module %s\n",
|
||||||
|
node.getModule().getClass().getName());
|
||||||
|
final InstalledModule installedModule = entityManager.find(
|
||||||
|
InstalledModule.class, node.
|
||||||
|
getModule().getClass().getName());
|
||||||
|
LOGGER.info("Status of module {} ({}): {}",
|
||||||
|
node.getModuleInfo().getModuleName(),
|
||||||
|
node.getModule().getClass().getName(),
|
||||||
|
installedModule.getStatus());
|
||||||
|
System.out.printf("Status of module %s (%s): %s\n",
|
||||||
|
node.getModuleInfo().getModuleName(),
|
||||||
|
node.getModule().getClass().getName(),
|
||||||
|
installedModule.getStatus());
|
||||||
|
System.out.printf("Checked status of module %s\n",
|
||||||
|
node.getModule().getClass().getName());
|
||||||
|
|
||||||
|
if (ModuleStatus.UNINSTALL.equals(installedModule.getStatus())) {
|
||||||
|
System.out.printf("Module %s is scheduled for uninstall...\n",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
if (node.getDependentModules().isEmpty()) {
|
||||||
|
System.out.
|
||||||
|
printf("Calling uninstall method of module %s...\n",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
final UnInstallEvent unInstallEvent = new UnInstallEvent();
|
||||||
|
unInstallEvent.setEntityManager(entityManager);
|
||||||
|
node.getModule().uninstall(null);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.printf("There are other modules depending on "
|
||||||
|
+ "module %s. Module can't be "
|
||||||
|
+ "uninstalled. Depending modules:\n",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
for (final TreeNode dependent : node.getDependentModules()) {
|
||||||
|
System.out.printf("\t%s\n",
|
||||||
|
dependent.getModuleInfo()
|
||||||
|
.getModuleName());
|
||||||
|
}
|
||||||
|
installedModule.setStatus(ModuleStatus.INSTALLED);
|
||||||
|
entityManager.merge(installedModule);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.printf(
|
||||||
|
"Module %s is *not* scheduled for uninstall.\n",
|
||||||
|
node.getModuleInfo().getModuleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ModuleManagerException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>ModuleManagerException</code> without
|
||||||
|
* detail message.
|
||||||
|
*/
|
||||||
|
public ModuleManagerException() {
|
||||||
|
//Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>ModuleManagerException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param msg the detail message.
|
||||||
|
*/
|
||||||
|
public ModuleManagerException(final String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleManagerException(final Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleManagerException(final String msg, final Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration describing the status of a module.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public enum ModuleStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a module as new. This state should be set by the DB migration
|
||||||
|
*/
|
||||||
|
NEW,
|
||||||
|
/**
|
||||||
|
* Marks a module as installed and ready to use.
|
||||||
|
*/
|
||||||
|
INSTALLED,
|
||||||
|
/**
|
||||||
|
* Marks a module be scheduled for uninstall. When the application is
|
||||||
|
* shutdown the module is removed from the database. Before starting the
|
||||||
|
* applications again the module classes (JAR) should be removed. Otherwise
|
||||||
|
* the module will be reinstalled.
|
||||||
|
*/
|
||||||
|
UNINSTALL
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public @interface RequiredModule {
|
||||||
|
|
||||||
|
Class<? extends CcmModule> module();
|
||||||
|
|
||||||
|
String minVersion() default "";
|
||||||
|
|
||||||
|
String maxVersion() default "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ShutdownEvent extends ModuleEvent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Represents a node in the dependency tree. This class is <strong>not</strong>
|
||||||
|
* part of the public API.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
final class TreeNode {
|
||||||
|
|
||||||
|
private CcmModule module;
|
||||||
|
private ModuleInfo moduleInfo;
|
||||||
|
private List<TreeNode> dependentModules;
|
||||||
|
private List<TreeNode> dependsOn;
|
||||||
|
|
||||||
|
public TreeNode() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
dependentModules = new ArrayList<>();
|
||||||
|
dependsOn = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode(final CcmModule module) {
|
||||||
|
this();
|
||||||
|
|
||||||
|
this.module = module;
|
||||||
|
final ModuleInfo info = new ModuleInfo();
|
||||||
|
info.load(module);
|
||||||
|
moduleInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CcmModule getModule() {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleInfo getModuleInfo() {
|
||||||
|
return moduleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TreeNode> getDependentModules() {
|
||||||
|
return Collections.unmodifiableList(dependentModules);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDependentModules(final List<TreeNode> dependentModules) {
|
||||||
|
this.dependentModules = dependentModules;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDependentModule(final TreeNode node) {
|
||||||
|
dependentModules.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeDependentModule(final TreeNode node) {
|
||||||
|
dependentModules.remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TreeNode> getDependsOn() {
|
||||||
|
return Collections.unmodifiableList(dependsOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDependsOn(final List<TreeNode> dependsOn) {
|
||||||
|
this.dependsOn = dependsOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDependsOn(final TreeNode node) {
|
||||||
|
dependsOn.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeDependsOn(final TreeNode node) {
|
||||||
|
dependsOn.remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 5;
|
||||||
|
|
||||||
|
final ModuleInfo info = new ModuleInfo();
|
||||||
|
info.load(module);
|
||||||
|
|
||||||
|
final String moduleName = info.getModuleName();
|
||||||
|
final String version = info.getModuleVersion();
|
||||||
|
|
||||||
|
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 = moduleInfo.getModuleName();
|
||||||
|
final String otherName = other.getModuleInfo().getModuleName();
|
||||||
|
|
||||||
|
if (!name.equals(otherName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String version = moduleInfo.getModuleVersion();
|
||||||
|
final String otherVersion = other.getModuleInfo().getModuleVersion();
|
||||||
|
|
||||||
|
return version.equals(otherVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.core.modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class UnInstallEvent extends ModuleEvent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_components")
|
@Table(name = "formbuilder_components", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_data_driven_selects")
|
@Table(name = "formbuilder_data_driven_selects", schema = "ccm_core")
|
||||||
public class DataDrivenSelect extends Widget implements Serializable {
|
public class DataDrivenSelect extends Widget implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4477753441663454661L;
|
private static final long serialVersionUID = -4477753441663454661L;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_formsections")
|
@Table(name = "formbuilder_formsections", schema = "ccm_core")
|
||||||
public class FormSection extends Component implements Serializable {
|
public class FormSection extends Component implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -3195157282292906945L;
|
private static final long serialVersionUID = -3195157282292906945L;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_listeners")
|
@Table(name = "formbuilder_listeners", schema = "ccm_core")
|
||||||
public class Listener extends CcmObject implements Serializable {
|
public class Listener extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 9030104813240364500L;
|
private static final long serialVersionUID = 9030104813240364500L;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = " formbuilder_metaobjects")
|
@Table(name = "formbuilder_metaobjects", schema = "ccm_core")
|
||||||
public class MetaObject extends CcmObject implements Serializable {
|
public class MetaObject extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -3770682858640493776L;
|
private static final long serialVersionUID = -3770682858640493776L;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_object_types")
|
@Table(name = "formbuilder_object_types", schema = "ccm_core")
|
||||||
public class ObjectType extends CcmObject implements Serializable {
|
public class ObjectType extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 5236718507025096569L;
|
private static final long serialVersionUID = 5236718507025096569L;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_options")
|
@Table(name = "formbuilder_options", schema = "ccm_core")
|
||||||
public class Option extends Component implements Serializable {
|
public class Option extends Component implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -7528058391772415511L;
|
private static final long serialVersionUID = -7528058391772415511L;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_data_queries")
|
@Table(name = "formbuilder_data_queries", schema = "ccm_core")
|
||||||
public class PersistentDataQuery extends CcmObject implements Serializable {
|
public class PersistentDataQuery extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -7344153915501267752L;
|
private static final long serialVersionUID = -7344153915501267752L;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_process_listeners")
|
@Table(name = "formbuilder_process_listeners", schema = "ccm_core")
|
||||||
public class ProcessListener extends CcmObject implements Serializable {
|
public class ProcessListener extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -3029184333026605708L;
|
private static final long serialVersionUID = -3029184333026605708L;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_widgets")
|
@Table(name = "formbuilder_widgets", schema = "ccm_core")
|
||||||
public class Widget extends Component implements Serializable {
|
public class Widget extends Component implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1057792450655098288L;
|
private static final long serialVersionUID = 1057792450655098288L;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_widget_labels")
|
@Table(name = "formbuilder_widget_labels", schema = "ccm_core")
|
||||||
public class WidgetLabel extends Component implements Serializable {
|
public class WidgetLabel extends Component implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2939505715812565159L;
|
private static final long serialVersionUID = -2939505715812565159L;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import org.libreccm.formbuilder.ProcessListener;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_confirm_email_listener")
|
@Table(name = "formbuilder_confirm_email_listener", schema = "ccm_core")
|
||||||
public class ConfirmEmailListener
|
public class ConfirmEmailListener
|
||||||
extends ProcessListener
|
extends ProcessListener
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.libreccm.formbuilder.ProcessListener;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_confirm_redirect_listeners")
|
@Table(name = "formbuilder_confirm_redirect_listeners", schema = "ccm_core")
|
||||||
public class ConfirmRedirectListener
|
public class ConfirmRedirectListener
|
||||||
extends ProcessListener
|
extends ProcessListener
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import org.libreccm.formbuilder.ProcessListener;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_remote_server_post_listener")
|
@Table(name = "formbuilder_remote_server_post_listener", schema = "ccm_core")
|
||||||
public class RemoteServerPostListener
|
public class RemoteServerPostListener
|
||||||
extends ProcessListener
|
extends ProcessListener
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import java.util.Objects;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_simple_email_listeners")
|
@Table(name = "formbuilder_simple_email_listeners", schema = "ccm_core")
|
||||||
public class SimpleEmailListener
|
public class SimpleEmailListener
|
||||||
extends ProcessListener
|
extends ProcessListener
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import org.libreccm.formbuilder.ProcessListener;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_template_email_listeners")
|
@Table(name = "formbuilder_template_email_listeners", schema = "ccm_core")
|
||||||
public class TemplateEmailListener
|
public class TemplateEmailListener
|
||||||
extends ProcessListener
|
extends ProcessListener
|
||||||
implements Serializable {
|
implements Serializable {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.libreccm.formbuilder.ProcessListener;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "formbuilder_xml_email_listeners")
|
@Table(name = "formbuilder_xml_email_listeners", schema = "ccm_core")
|
||||||
public class XmlEmailListener extends ProcessListener implements Serializable {
|
public class XmlEmailListener extends ProcessListener implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4607965414018004925L;
|
private static final long serialVersionUID = -4607965414018004925L;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "attachments")
|
@Table(name = "attachments", schema = "ccm_core")
|
||||||
public class Attachment implements Serializable {
|
public class Attachment implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2063934721452863106L;
|
private static final long serialVersionUID = 2063934721452863106L;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import javax.persistence.TemporalType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "messages")
|
@Table(name = "messages", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "threads")
|
@Table(name = "threads", schema = "ccm_core")
|
||||||
public class MessageThread extends CcmObject implements Serializable {
|
public class MessageThread extends CcmObject implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -395123286904985770L;
|
private static final long serialVersionUID = -395123286904985770L;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.modules;
|
package org.libreccm.modules;
|
||||||
|
|
||||||
|
import com.arsdigita.runtime.RegistryConfig;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.enterprise.inject.Instance;
|
import javax.enterprise.inject.Instance;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -28,10 +33,62 @@ import javax.inject.Inject;
|
||||||
*/
|
*/
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class ModuleManager {
|
public class ModuleManager {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private transient Instance<ModuleDescriptor> modules;
|
private transient Instance<ModuleDescriptor> modules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for new or upgraded modules and executes database migrations if
|
||||||
|
* necessary. If a new module is installed the database tables for this
|
||||||
|
* module are generated first. After that the {@code prepare()} method of
|
||||||
|
* the module is called (see {@link ModuleDescriptor#prepare()}).
|
||||||
|
*/
|
||||||
|
public void loadModules() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a module is already installed.
|
||||||
|
*
|
||||||
|
* @param moduleDescriptor The descriptor of the module.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the module is already installed, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
private boolean isInstalled(final ModuleDescriptor moduleDescriptor) {
|
||||||
|
final RegistryConfig registryConfig = new RegistryConfig();
|
||||||
|
registryConfig.load();
|
||||||
|
final String[] packages = registryConfig.getPackages();
|
||||||
|
final List<String> packageList = Arrays.asList(packages);
|
||||||
|
|
||||||
|
return packageList.contains(ModuleUtil.getModuleName(moduleDescriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to uninstall a module. First the {@code uninstal()} method of the
|
||||||
|
* module is called (see {@link ModuleDescriptor#uninstall()}). After that
|
||||||
|
* the database tables of the module are removed.
|
||||||
|
*
|
||||||
|
* @param module The module to uninstall.
|
||||||
|
*/
|
||||||
|
public void uninstallModule(final ModuleDescriptor module) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises all modules by calling their {@code init()} method (see
|
||||||
|
* {@link ModuleDescriptor#init()}.
|
||||||
|
*/
|
||||||
|
public void initModules() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown all modules by calling their {@link shutdown()} method (see
|
||||||
|
* {@link ModuleDescriptor#shutdown()}).
|
||||||
|
*/
|
||||||
|
public void shutdownModules() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import javax.persistence.TemporalType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "digests")
|
@Table(name = "digests", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ import javax.persistence.TemporalType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "notifications")
|
@Table(name = "notifications", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet. Not sure what to do about the God class warning.
|
//Can't reduce complexity yet. Not sure what to do about the God class warning.
|
||||||
//Maybe we have to put some of the properties into an extra class.
|
//Maybe we have to put some of the properties into an extra class.
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "queue_items")
|
@Table(name = "queue_items", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "portals")
|
@Table(name = "portals", schema = "ccm_core")
|
||||||
public class Portal extends Resource implements Serializable {
|
public class Portal extends Resource implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -5492307663469206053L;
|
private static final long serialVersionUID = -5492307663469206053L;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "portlets")
|
@Table(name = "portlets", schema = "ccm_core")
|
||||||
public class Portlet extends Resource implements Serializable {
|
public class Portlet extends Resource implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -5718126018588744104L;
|
private static final long serialVersionUID = -5718126018588744104L;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "inits")
|
@Table(name = "inits", schema = "ccm_core")
|
||||||
public class Initalizer implements Serializable {
|
public class Initalizer implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 9150623897315380159L;
|
private static final long serialVersionUID = 9150623897315380159L;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import javax.persistence.TemporalType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "lucene_documents")
|
@Table(name = "lucene_documents", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet. Not sure what to do about the God class warning.
|
//Can't reduce complexity yet. Not sure what to do about the God class warning.
|
||||||
//Maybe we have to put some of the properties into an extra class.
|
//Maybe we have to put some of the properties into an extra class.
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "lucene_indexes")
|
@Table(name = "lucene_indexes", schema = "ccm_core")
|
||||||
public class Index implements Serializable {
|
public class Index implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3197625173477366719L;
|
private static final long serialVersionUID = 3197625173477366719L;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "applications")
|
@Table(name = "applications", schema = "ccm_core")
|
||||||
@XmlRootElement(name = "application", namespace = WEB_XML_NS)
|
@XmlRootElement(name = "application", namespace = WEB_XML_NS)
|
||||||
public class Application extends Resource implements Serializable {
|
public class Application extends Resource implements Serializable {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import org.libreccm.core.ResourceType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "application_types")
|
@Table(name = "application_types", schema = "ccm_core")
|
||||||
@SuppressWarnings("PMD.LongVariable")
|
@SuppressWarnings("PMD.LongVariable")
|
||||||
public class ApplicationType extends ResourceType implements Serializable {
|
public class ApplicationType extends ResourceType implements Serializable {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import javax.persistence.UniqueConstraint;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "hosts",
|
@Table(name = "hosts", schema = "ccm_core",
|
||||||
uniqueConstraints = {
|
uniqueConstraints = {
|
||||||
@UniqueConstraint(columnNames = {"server_name", "server_port"})})
|
@UniqueConstraint(columnNames = {"server_name", "server_port"})})
|
||||||
@SuppressWarnings("PMD.ShortClassName") //Host is perfectly fine as class name...
|
@SuppressWarnings("PMD.ShortClassName") //Host is perfectly fine as class name...
|
||||||
|
|
@ -114,10 +114,10 @@ public class Host implements Serializable {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%s{ "
|
return String.format("%s{ "
|
||||||
+ "hostId = %d, "
|
+ "hostId = %d, "
|
||||||
+ "serverName = \"%s\", "
|
+ "serverName = \"%s\", "
|
||||||
+ "serverPort =\"%s\""
|
+ "serverPort =\"%s\""
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
hostId,
|
hostId,
|
||||||
serverName,
|
serverName,
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "workflow_tasks")
|
@Table(name = "workflow_tasks", schema = "ccm_core")
|
||||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||||
//Can't reduce complexity yet, Task is a fine name
|
//Can't reduce complexity yet, Task is a fine name
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import javax.persistence.TemporalType;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "workflow_user_tasks")
|
@Table(name = "workflow_user_tasks", schema = "ccm_core")
|
||||||
//Can't reduce complexity yet
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import javax.persistence.Table;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "workflows")
|
@Table(name = "workflows", schema = "ccm_core")
|
||||||
public class Workflow implements Serializable {
|
public class Workflow implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4322500264543325829L;
|
private static final long serialVersionUID = 4322500264543325829L;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
|
||||||
<jta-data-source>
|
<jta-data-source>
|
||||||
java:/comp/env/jdbc/website_study_tool/db
|
java:/comp/env/jdbc/ccm-core/db
|
||||||
</jta-data-source>
|
</jta-data-source>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
org.libreccm.core.modules.CcmIntegrator
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
org.libreccm.core.CcmCore
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
groupId=${project.groupId}
|
||||||
|
artifactId=${project.artifactId}
|
||||||
|
version=${project.version}
|
||||||
|
build.date=${timestamp}
|
||||||
|
|
@ -18,15 +18,19 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.core;
|
package org.libreccm.core;
|
||||||
|
|
||||||
|
import org.dbunit.database.DatabaseConnection;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
|
||||||
import org.jboss.arquillian.container.test.api.Deployment;
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
import org.jboss.arquillian.container.test.api.ShouldThrowException;
|
import org.jboss.arquillian.container.test.api.ShouldThrowException;
|
||||||
import org.jboss.arquillian.junit.Arquillian;
|
import org.jboss.arquillian.junit.Arquillian;
|
||||||
import org.jboss.arquillian.junit.InSequence;
|
import org.jboss.arquillian.junit.InSequence;
|
||||||
|
import org.jboss.arquillian.persistence.CreateSchema;
|
||||||
import org.jboss.arquillian.persistence.PersistenceTest;
|
import org.jboss.arquillian.persistence.PersistenceTest;
|
||||||
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
|
import org.jboss.arquillian.persistence.ShouldMatchDataSet;
|
||||||
import org.jboss.arquillian.persistence.UsingDataSet;
|
import org.jboss.arquillian.persistence.UsingDataSet;
|
||||||
|
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||||
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
|
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
|
||||||
import org.jboss.arquillian.transaction.api.annotation.Transactional;
|
import org.jboss.arquillian.transaction.api.annotation.Transactional;
|
||||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
|
@ -60,6 +64,7 @@ import static org.junit.Assert.*;
|
||||||
@RunWith(Arquillian.class)
|
@RunWith(Arquillian.class)
|
||||||
@PersistenceTest
|
@PersistenceTest
|
||||||
@Transactional(TransactionMode.COMMIT)
|
@Transactional(TransactionMode.COMMIT)
|
||||||
|
//@CreateSchema({"scripts/create_ccm_core_schema.sql"})
|
||||||
public class CcmObjectRepositoryTest {
|
public class CcmObjectRepositoryTest {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,11 @@ public class DatasetsTest extends DatasetsVerifier {
|
||||||
super(datasetPath);
|
super(datasetPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSchemas() {
|
||||||
|
return new String[]{ "ccm_core" };
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() {
|
public static void setUpClass() {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* 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.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.libreccm.tests.categories.UnitTest;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Category(UnitTest.class)
|
||||||
|
public class DependencyTreeManagerValidateVersionTest {
|
||||||
|
|
||||||
|
public DependencyTreeManagerValidateVersionTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateVersions() throws NoSuchMethodException,
|
||||||
|
IllegalAccessException,
|
||||||
|
IllegalArgumentException,
|
||||||
|
InvocationTargetException {
|
||||||
|
final DependencyTreeManager treeManager = new DependencyTreeManager();
|
||||||
|
final Method validate = treeManager.getClass().getDeclaredMethod(
|
||||||
|
"validateVersion",
|
||||||
|
String.class,
|
||||||
|
String.class,
|
||||||
|
String.class);
|
||||||
|
|
||||||
|
validate.setAccessible(true);
|
||||||
|
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
"1.0.0",
|
||||||
|
"1.0.0"),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
"1.0.0",
|
||||||
|
""),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
"1.0.0",
|
||||||
|
null),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
"",
|
||||||
|
"1.0.0"),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
null,
|
||||||
|
"1.0.0"),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
"",
|
||||||
|
""),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.0.0",
|
||||||
|
null,
|
||||||
|
null),
|
||||||
|
is(true));
|
||||||
|
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.7.5",
|
||||||
|
"1.0.0",
|
||||||
|
""),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.7.5-beta.3",
|
||||||
|
"1.0.0",
|
||||||
|
""),
|
||||||
|
is(true));
|
||||||
|
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.7.5",
|
||||||
|
"1.0.0",
|
||||||
|
"1.7.9"),
|
||||||
|
is(true));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.7.5-final",
|
||||||
|
"1.7.5",
|
||||||
|
""),
|
||||||
|
is(true));
|
||||||
|
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.5.3",
|
||||||
|
"1.6.0",
|
||||||
|
""),
|
||||||
|
is(false));
|
||||||
|
assertThat((boolean) validate.invoke(treeManager,
|
||||||
|
"1.6.0",
|
||||||
|
"1.5.0",
|
||||||
|
"1.5.9"),
|
||||||
|
is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -28,11 +28,12 @@
|
||||||
<property name="defaultDataSetFormat">json</property>
|
<property name="defaultDataSetFormat">json</property>
|
||||||
<property name="datatypeFactory">org.dbunit.ext.h2.H2DataTypeFactory</property>
|
<property name="datatypeFactory">org.dbunit.ext.h2.H2DataTypeFactory</property>
|
||||||
<property name="excludePoi">true</property>
|
<property name="excludePoi">true</property>
|
||||||
|
<property name="qualifiedTableNames">true</property>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension qualifier="persistence-script">
|
<!--<extension qualifier="persistence-script">
|
||||||
<property name="scriptsToExecuteAfterTest">scripts/h2-cleanup.sql</property>
|
<property name="scriptsToExecuteAfterTest">scripts/h2-cleanup.sql</property>
|
||||||
</extension>
|
</extension>-->
|
||||||
|
|
||||||
|
|
||||||
</arquillian>
|
</arquillian>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -28,11 +28,12 @@
|
||||||
<property name="defaultDataSetFormat">json</property>
|
<property name="defaultDataSetFormat">json</property>
|
||||||
<!--<property name="datatypeFactory">org.dbunit.ext.h2.H2DataTypeFactory</property>-->
|
<!--<property name="datatypeFactory">org.dbunit.ext.h2.H2DataTypeFactory</property>-->
|
||||||
<property name="excludePoi">true</property>
|
<property name="excludePoi">true</property>
|
||||||
|
<property name="qualifiedTableNames">true</property>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension qualifier="persistence-script">
|
<!--<extension qualifier="persistence-script">
|
||||||
<property name="scriptsToExecuteAfterTest">scripts/pgsql-cleanup.sql</property>
|
<property name="scriptsToExecuteAfterTest">scripts/pgsql-cleanup.sql</property>
|
||||||
</extension>
|
</extension>-->
|
||||||
|
|
||||||
|
|
||||||
</arquillian>
|
</arquillian>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"subject_id": -30
|
"subject_id": -30
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"subject_id": -30
|
"subject_id": -30
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"subject_id": -30
|
"subject_id": -30
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"display_name": "Test Object 8"
|
"display_name": "Test Object 8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
"label": "write"
|
"label": "write"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -1
|
"subject_id": -1
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "users",
|
"name": "users",
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"display_name": "Test Object 8"
|
"display_name": "Test Object 8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
"label": "write"
|
"label": "write"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -1
|
"subject_id": -1
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "users",
|
"name": "users",
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"display_name": "Test Object 8"
|
"display_name": "Test Object 8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
"label": "write"
|
"label": "write"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -1
|
"subject_id": -1
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "users",
|
"name": "users",
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
"display_name": "Test Object 8"
|
"display_name": "Test Object 8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
"label": "write"
|
"label": "write"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -1
|
"subject_id": -1
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "users",
|
"name": "users",
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -156,7 +156,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -109,7 +109,7 @@
|
||||||
"label": "unused"
|
"label": "unused"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"display_name": "Test Object 4"
|
"display_name": "Test Object 4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"subjects":
|
"ccm_core.subjects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"subject_id": -10
|
"subject_id": -10
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_users":
|
"ccm_core.ccm_users":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"banned": false,
|
"banned": false,
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
"subject_id": -50
|
"subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_groups":
|
"ccm_core.ccm_groups":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "admins",
|
"name": "admins",
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
"subject_id": -40
|
"subject_id": -40
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"user_email_addresses":
|
"ccm_core.user_email_addresses":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"user_id": -10,
|
"user_id": -10,
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
"verified": true
|
"verified": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"group_memberships":
|
"ccm_core.group_memberships":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"membership_id": -10,
|
"membership_id": -10,
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
"user_subject_id": -50
|
"user_subject_id": -50
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_privileges":
|
"ccm_core.ccm_privileges":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"privilege_id": -10,
|
"privilege_id": -10,
|
||||||
|
|
@ -109,7 +109,7 @@
|
||||||
"label": "unused"
|
"label": "unused"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ccm_objects":
|
"ccm_core.ccm_objects":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"object_id": -10,
|
"object_id": -10,
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
"display_name": "Test Object 4"
|
"display_name": "Test Object 4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions":
|
"ccm_core.permissions":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"permission_id": -10,
|
"permission_id": -10,
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue