Some missing IdResolvers, added scope attributes to all

@JsonIdentityInfo annoations
deploy_packages_to_gitea
Jens Pelzetter 2022-11-29 19:35:41 +01:00
parent 75a499e70d
commit 5c140fd98f
44 changed files with 833 additions and 152 deletions

View File

@ -52,7 +52,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ContactableEntityIdResolver.class,
property = "uuid"
property = "uuid",
scope = ContactableEntity.class
)
public class ContactableEntity extends Asset {

View File

@ -56,7 +56,8 @@ import static org.librecms.assets.AssetConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = OrganizationIdResolver.class,
property = "uuid"
property = "uuid",
scope = Organization.class
)
public class Organization extends ContactableEntity {

View File

@ -18,7 +18,6 @@
*/
package org.librecms.assets;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited;
@ -71,7 +70,8 @@ import static org.librecms.assets.AssetConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PersonIdResolver.class,
property = "uuid"
property = "uuid",
scope = Person.class
)
public class Person extends ContactableEntity {

View File

@ -57,7 +57,8 @@ import static org.librecms.assets.AssetConstants.ASSETS_BUNDLE;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PostalAddressIdResolver.class,
property = "uuid"
property = "uuid",
scope = PostalAddress.class
)
public class PostalAddress extends Asset {

View File

@ -580,7 +580,8 @@ import javax.xml.bind.annotation.XmlElementWrapper;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ContentItemIdResolver.class,
property = "uuid"
property = "uuid",
scope = ContentItem.class
)
public class ContentItem extends CcmObject implements Serializable, Exportable {

View File

@ -80,7 +80,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ContentTypeIdResolver.class,
property = "uuid"
property = "uuid",
scope = ContentType.class
)
public class ContentType extends CcmObject implements Serializable {

View File

@ -310,7 +310,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = FolderIdResolver.class,
property = "uuid"
property = "uuid",
scope = Folder.class
)
public class Folder extends Category implements Serializable {

View File

@ -66,7 +66,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = LifecycleIdResolver.class,
property = "uuid"
property = "uuid",
scope = Lifecycle.class
)
public class Lifecycle implements Exportable, Identifiable, Serializable {

View File

@ -65,7 +65,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = LifecycleDefinitionIdResolver.class,
property = "uuid"
property = "uuid",
scope = LifecycleDefinition.class
)
public class LifecycleDefinition
implements Identifiable, Exportable, Serializable {

View File

@ -58,7 +58,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PhaseIdResolver.class,
property = "uuid"
property = "uuid",
scope = Phase.class
)
public class Phase implements Exportable, Serializable {

View File

@ -57,7 +57,8 @@ import static org.librecms.CmsConstants.*;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PhaseDefinitionIdResolver.class,
property = "uuid"
property = "uuid",
scope = PhaseDefinition.class
)
public class PhaseDefinition implements Exportable, Serializable {

View File

@ -104,7 +104,9 @@ import javax.persistence.Table;
})
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid"
resolver = CategorizationIdResolver.class,
property = "uuid",
scope = Categorization.class
)
public class Categorization implements Serializable, Relation, Exportable {

View File

@ -0,0 +1,51 @@
package org.libreccm.categorization;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategorizationIdResolver implements ObjectIdResolver, Serializable{
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey id, final Object object
) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(CategorizationRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No Categorization with UUID %s in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new CategorizationIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof CategorizationIdResolver;
}
}

View File

@ -0,0 +1,54 @@
package org.libreccm.categorization;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.persistence.NoResultException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategorizationRepository
extends AbstractEntityRepository<Long, Categorization> {
private static final long serialVersionUID = 1L;
@Override
public Class<Categorization> getEntityClass() {
return Categorization.class;
}
@Override
public String getIdAttributeName() {
return "categorizationId";
}
@Override
public Long getIdOfEntity(final Categorization entity) {
return entity.getCategorizationId();
}
@Override
public boolean isNew(final Categorization entity) {
return entity.getCategorizationId()== 0;
}
public Optional<Categorization> findByUuid(final String uuid) {
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"Categorization.findByUuid",
Categorization.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -138,7 +138,8 @@ import javax.validation.constraints.NotBlank;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = CategoryIdResolver.class,
property = "uuid"
property = "uuid",
scope = Category.class
)
public class Category extends CcmObject implements Serializable, Exportable {

View File

@ -133,9 +133,12 @@ import javax.validation.constraints.NotBlank;
)
})
@XmlRootElement(name = "domain", namespace = CAT_XML_NS)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = DomainIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = DomainIdResolver.class,
property = "uuid",
scope = Domain.class
)
public class Domain extends CcmObject implements Serializable, Exportable {
private static final long serialVersionUID = 4012590760598188732L;

View File

@ -68,8 +68,12 @@ import javax.xml.bind.annotation.XmlElement;
query = "SELECT o FROM DomainOwnership o "
+ "WHERE o.owner = :owner AND o.domain = :domain")
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid",
resolver = DomainOwnershipIdResolver.class,
scope = DomainOwnership.class
)
public class DomainOwnership implements Serializable, Exportable {
private static final long serialVersionUID = 201504301305L;

View File

@ -0,0 +1,51 @@
package org.libreccm.categorization;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class DomainOwnershipIdResolver implements ObjectIdResolver, Serializable{
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey id, final Object object
) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(DomainOwnershipRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No DomainOwnership with UUID %s in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new DomainOwnershipIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof DomainOwnershipIdResolver;
}
}

View File

@ -0,0 +1,54 @@
package org.libreccm.categorization;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.persistence.NoResultException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class DomainOwnershipRepository
extends AbstractEntityRepository<Long, DomainOwnership> {
private static final long serialVersionUID = 1L;
@Override
public Class<DomainOwnership> getEntityClass() {
return DomainOwnership.class;
}
@Override
public String getIdAttributeName() {
return "ownershipId";
}
@Override
public Long getIdOfEntity(final DomainOwnership entity) {
return entity.getOwnershipId();
}
@Override
public boolean isNew(final DomainOwnership entity) {
return entity.getOwnershipId()== 0;
}
public Optional<DomainOwnership> findByUuid(final String uuid) {
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"DomainOwnership.findByUuid",
DomainOwnership.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -90,9 +90,12 @@ import javax.persistence.Table;
//persistence system we can't yet refactor it to make PMD happy. Also I think
//this is a false warning.
@SuppressWarnings("PMD.TooManyMethods")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = CcmObjectIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = CcmObjectIdResolver.class,
property = "uuid",
scope = CcmObject.class
)
public class CcmObject implements Exportable, Identifiable, Serializable {
private static final long serialVersionUID = 201504261329L;

View File

@ -69,12 +69,14 @@ import javax.persistence.TemporalType;
@Entity
@Table(name = "RESOURCES", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Resource.findByUuid",
query = "SELECT r FROM Resource r WHERE r.uuid = :uuid"),
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ResourceIdResolver.class,
property = "uuid")
@NamedQuery(name = "Resource.findByUuid",
query = "SELECT r FROM Resource r WHERE r.uuid = :uuid"),})
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ResourceIdResolver.class,
property = "uuid",
scope = Resource.class
)
public class Resource extends CcmObject implements Serializable, Exportable {
private static final long serialVersionUID = 7345482620613842781L;

View File

@ -60,14 +60,16 @@ import javax.persistence.Table;
@Inheritance(strategy = InheritanceType.JOINED)
@NamedQueries({
@NamedQuery(name = "ResourceType.findByUuid",
query = "SELECT r FROM ResourceType r WHERE r.uuid = :uuid")
,
@NamedQuery(name = "ResourceType.findByTitle",
query = "SELECT r FROM ResourceType r WHERE r.uuid = :uuid"),
@NamedQuery(name = "ResourceType.findByTitle",
query = "SELECT r FROM ResourceType r WHERE r.title = :title")
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ResourceTypeIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ResourceTypeIdResolver.class,
property = "uuid",
scope = ResourceType.class
)
@SuppressWarnings({"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity",

View File

@ -66,18 +66,15 @@ import javax.persistence.Table;
@NamedQuery(
name = "Group.findByName",
query = "SELECT g FROM Group g WHERE g.name = :name "
+ "ORDER BY g.name")
,
+ "ORDER BY g.name"),
@NamedQuery(
name = "Group.searchByName",
query = "SELECT g FROM Group g "
+ "WHERE LOWER(g.name) LIKE CONCAT(LOWER(:name), '%') "
+ "ORDER BY g.name")
,
+ "ORDER BY g.name"),
@NamedQuery(
name = "Group.findAllOrderedByGroupName",
query = "SELECT g FROM Group g ORDER BY g.name")
,
query = "SELECT g FROM Group g ORDER BY g.name"),
@NamedQuery(
name = "Group.findByMember",
query = "SELECT g FROM Group g "
@ -89,8 +86,7 @@ import javax.persistence.Table;
@NamedEntityGraph(
name = "Group.withMembersAndRoleMemberships",
attributeNodes = {
@NamedAttributeNode(value = "memberships")
,
@NamedAttributeNode(value = "memberships"),
@NamedAttributeNode(value = "roleMemberships",
subgraph = "role")},
subgraphs = {
@ -99,8 +95,7 @@ import javax.persistence.Table;
attributeNodes = {
@NamedAttributeNode(value = "role",
subgraph = "permissions")
})
,
}),
@NamedSubgraph(
name = "permissions",
attributeNodes = {
@ -108,9 +103,12 @@ import javax.persistence.Table;
})
})
@XmlRootElement(name = "user-group", namespace = CORE_XML_NS)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = GroupIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = GroupIdResolver.class,
property = "uuid",
scope = Group.class
)
public class Group extends Party implements Serializable, Exportable {
private static final long serialVersionUID = -4800759206452780739L;

View File

@ -73,7 +73,9 @@ import javax.persistence.Table;
@XmlRootElement(name = "group-membership", namespace = CORE_XML_NS)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid"
property = "uuid",
resolver = GroupMembershipIdResolver.class,
scope = GroupMembership.class
)
public class GroupMembership implements Serializable, Exportable {

View File

@ -0,0 +1,51 @@
package org.libreccm.security;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class GroupMembershipIdResolver implements ObjectIdResolver, Serializable{
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey id, final Object object
) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(GroupMembershipRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No GroupMembership with UUID %s in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new GroupMembershipIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof GroupMembershipIdResolver;
}
}

View File

@ -0,0 +1,54 @@
package org.libreccm.security;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.persistence.NoResultException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class GroupMembershipRepository
extends AbstractEntityRepository<Long, GroupMembership> {
private static final long serialVersionUID = 1L;
@Override
public Class<GroupMembership> getEntityClass() {
return GroupMembership.class;
}
@Override
public String getIdAttributeName() {
return "membershipId";
}
@Override
public Long getIdOfEntity(final GroupMembership entity) {
return entity.getMembershipId();
}
@Override
public boolean isNew(final GroupMembership entity) {
return entity.getMembershipId() == 0;
}
public Optional<GroupMembership> findByUuid(final String uuid) {
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"GroupMembership.findByUuid",
GroupMembership.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -89,9 +89,12 @@ import javax.persistence.Table;
attributeNodes = @NamedAttributeNode(
value = "roleMemberships"))
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PartyIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PartyIdResolver.class,
property = "uuid",
scope = Party.class
)
public class Party implements Serializable {
private static final long serialVersionUID = 3319997992281332204L;

View File

@ -105,9 +105,12 @@ import javax.persistence.TemporalType;
})
@XmlRootElement(name = "permission", namespace = CORE_XML_NS)
@XmlAccessorType(XmlAccessType.FIELD)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PermissionIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PermissionIdResolver.class,
property = "uuid",
scope = Permission.class
)
public class Permission implements Serializable, Exportable {
private static final long serialVersionUID = -5178045844045517958L;

View File

@ -75,55 +75,45 @@ import javax.xml.bind.annotation.XmlRootElement;
query = "SELECT r FROM Role r WHERE r.uuid = :uuid"),
@NamedQuery(name = "Role.findByName",
query = "SELECT r FROM Role r "
+ "WHERE r.name = :name")
,
+ "WHERE r.name = :name"),
@NamedQuery(
name = "Role.count",
query = "SELECT COUNT(r) FROM Role r")
,
query = "SELECT COUNT(r) FROM Role r"),
@NamedQuery(
name = "Role.findAllOrderedByRoleName",
query = "SELECT r FROM Role r ORDER BY r.name")
,
query = "SELECT r FROM Role r ORDER BY r.name"),
@NamedQuery(
name = "Role.findAllOrderedByRoleNameLimit",
query = "SELECT r FROM Role r ORDER BY r.name ")
,
query = "SELECT r FROM Role r ORDER BY r.name "),
@NamedQuery(
name = "Role.findAllOrderedByRoleNameDesc",
query = "SELECT r FROM Role r ORDER BY r.name DESC")
,
query = "SELECT r FROM Role r ORDER BY r.name DESC"),
@NamedQuery(
name = "Role.searchByName",
query = "SELECT r FROM Role r "
+ "WHERE LOWER(r.name) LIKE CONCAT(LOWER(:name), '%') "
+ "ORDER BY r.name ")
,
+ "ORDER BY r.name "),
@NamedQuery(
name = "Role.searchByNameCount",
query = "SELECT COUNT(r.name) FROM Role r "
+ "WHERE LOWER(r.name) LIKE CONCAT(LOWER(:name), '%') "
+ "GROUP BY r.name "
+ "ORDER BY r.name ")
,
+ "ORDER BY r.name "),
@NamedQuery(
name = "Role.findByPrivilege",
query = "SELECT r FROM Role r JOIN r.permissions p "
+ "WHERE p.grantedPrivilege = :privilege "
+ "ORDER BY r.name")
,
+ "ORDER BY r.name"),
@NamedQuery(
name = "Role.findByPrivilegeAndObject",
query = "SELECT r FROM Role r JOIN r.permissions p "
+ "WHERE p.grantedPrivilege = :privilege "
+ "AND p.object = :object "
+ "ORDER BY r.name")
,
+ "ORDER BY r.name"),
@NamedQuery(
name = "Role.findRolesOfUser",
query = "SELECT r.role FROM RoleMembership r "
+ "WHERE r.member = :user")
,
+ "WHERE r.member = :user"),
@NamedQuery(
name = "Role.findByParty",
query = "SELECT r FROM Role r "
@ -135,8 +125,7 @@ import javax.xml.bind.annotation.XmlRootElement;
@NamedEntityGraph(
name = Role.ENTITY_GRPAH_WITH_MEMBERS,
attributeNodes = {
@NamedAttributeNode(value = "memberships"),})
,
@NamedAttributeNode(value = "memberships"),}),
@NamedEntityGraph(
name = Role.ENTITY_GRPAH_WITH_PERMISSIONS,
attributeNodes = {
@ -146,17 +135,21 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "role", namespace = CORE_XML_NS)
@XmlAccessorType(XmlAccessType.FIELD)
@SuppressWarnings({"PMD.ShortClassName", "PMD.TooManyMethods"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = RoleIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = RoleIdResolver.class,
property = "uuid",
scope = Role.class
)
public class Role implements Serializable, Exportable {
private static final long serialVersionUID = -7121296514181469687L;
public static final String ENTITY_GRPAH_WITH_MEMBERS
= "Role.withMembers";
= "Role.withMembers";
public static final String ENTITY_GRPAH_WITH_PERMISSIONS
= "Role.withPermissions";
= "Role.withPermissions";
@Id
@Column(name = "ROLE_ID")

View File

@ -72,8 +72,12 @@ import javax.persistence.Table;
)
})
@XmlRootElement(name = "role-membership", namespace = CORE_XML_NS)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid",
resolver = RoleMembershipIdResolver.class,
scope = RoleMembership.class
)
public class RoleMembership implements Serializable, Exportable {
private static final long serialVersionUID = -3049727720697964793L;

View File

@ -0,0 +1,51 @@
package org.libreccm.security;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class RoleMembershipIdResolver implements ObjectIdResolver, Serializable{
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey id, final Object object
) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(RoleMembershipRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No RoleMembership with UUID %s in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new RoleMembershipIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof RoleMembershipIdResolver;
}
}

View File

@ -0,0 +1,52 @@
package org.libreccm.security;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.persistence.NoResultException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class RoleMembershipRepository
extends AbstractEntityRepository<Long, RoleMembership> {
@Override
public Class<RoleMembership> getEntityClass() {
return RoleMembership.class;
}
@Override
public String getIdAttributeName() {
return "membershipId";
}
@Override
public Long getIdOfEntity(final RoleMembership entity) {
return entity.getMembershipId();
}
@Override
public boolean isNew(final RoleMembership entity) {
return entity.getMembershipId() == 0;
}
public Optional<RoleMembership> findByUuid(final String uuid) {
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"RoleMembership.findByUuid",
RoleMembership.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -147,9 +147,12 @@ import javax.xml.bind.annotation.XmlTransient;
//Supressing a few warnings from PMD because they misleading here.
//User is perfectly fine class name, and the complexity is not to high...
@SuppressWarnings({"PMD.ShortClassName", "PMD.LongVariable"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = UserIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = UserIdResolver.class,
property = "uuid",
scope = User.class
)
public class User extends Party implements Serializable, Exportable {
private static final long serialVersionUID = 4035223413596611393L;

View File

@ -78,9 +78,12 @@ import javax.persistence.Table;
})
})
@XmlRootElement(name = "application", namespace = WEB_XML_NS)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ApplicationIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ApplicationIdResolver.class,
property = "uuid",
scope = CcmApplication.class
)
public class CcmApplication extends Resource implements Serializable,
Exportable {

View File

@ -59,27 +59,23 @@ import javax.persistence.TemporalType;
@NamedQueries({
@NamedQuery(
name = "AssignableTask.findByUuid",
query = "SELECT t FROM AssignableTask t WHERE t.uuid = :uuid")
,
query = "SELECT t FROM AssignableTask t WHERE t.uuid = :uuid"),
@NamedQuery(
name = "AssignableTask.findLockedBy",
query = "SELECT t FROM AssignableTask t WHERE t.lockingUser = :user")
,
query = "SELECT t FROM AssignableTask t WHERE t.lockingUser = :user"),
@NamedQuery(
name = "AssignableTask.findEnabledTasksForWorkflow",
query = "SELECT t FROM AssignableTask t "
+ "WHERE t.lockingUser = :user "
+ "AND t.workflow = :workflow"
)
,
),
@NamedQuery(
name = "AssignableTask.findAssignedTasks",
query = "SELECT DISTINCT t FROM AssignableTask t "
+ "JOIN t.assignments a "
+ "WHERE a.role IN :roles "
+ "AND t.workflow = :workflow "
+ "AND t.active = true")
,
+ "AND t.active = true"),
@NamedQuery(
name = "AssignableTask.isAssignedTo",
query = "SELECT (CASE WHEN COUNT(t) > 0 THEN true ELSE false END) "
@ -87,8 +83,7 @@ import javax.persistence.TemporalType;
+ "JOIN t.assignments a "
+ "WHERE a.role IN :roles "
+ "AND t = :task"
)
,
),
@NamedQuery(
name = "AssignableTask.findOverdueTasks",
query = "SELECT t FROM AssignableTask t "
@ -99,9 +94,12 @@ import javax.persistence.TemporalType;
@SuppressWarnings({"PMD.CyclomaticComplexity",
"PMD.StdCyclomaticComplexity",
"PMD.ModifiedCyclomaticComplexity"})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = AssignableTaskIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = AssignableTaskIdResolver.class,
property = "uuid",
scope = AssignableTask.class
)
public class AssignableTask extends Task implements Serializable, Exportable {
private static final long serialVersionUID = 4188064584389893019L;

View File

@ -77,44 +77,38 @@ import javax.xml.bind.annotation.XmlElementWrapper;
@NamedQueries({
@NamedQuery(
name = "Task.findByUuid",
query = "SELECT t FROM Task t WHERE t.uuid = :uuid")
,
query = "SELECT t FROM Task t WHERE t.uuid = :uuid"),
@NamedQuery(
name = "Task.countUnfinishedAndActiveTasksForWorkflow",
query = "SELECT COUNT(t) FROM Task t "
+ "WHERE t.taskState != org.libreccm.workflow.TaskState.FINISHED "
+ "AND t.active = true "
+ "AND t.workflow = :workflow")
,
+ "AND t.workflow = :workflow"),
@NamedQuery(
name = "Task.countUnfinishedTasksForWorkflow",
query = "SELECT COUNT(t) FROM Task t "
+ "WHERE t.taskState != org.libreccm.workflow.TaskState.FINISHED "
+ "AND t.workflow = :workflow"
)
,
),
@NamedQuery(
name = "Task.findEnabledTasks",
query = "SELECT t FROM Task t "
+ "WHERE t.workflow = :workflow "
+ "AND t.taskState = org.libreccm.workflow.TaskState.ENABLED "
+ "AND t.active = true"
)
,
),
@NamedQuery(
name = "Task.findFinishedTasks",
query = "SELECT t FROM Task t "
+ "WHERE t.workflow = :workflow "
+ "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED")
,
+ "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED"),
@NamedQuery(
name = "Task.existsDependency",
query = "SELECT (CASE WHEN COUNT(d) > 0 THEN true ELSE false END) "
+ "FROM TaskDependency d "
+ "WHERE d.blockedTask = :blockedTask "
+ "AND d.blockingTask = :blockingTask"
)
,
),
@NamedQuery(
name = "Task.findDependency",
query = "SELECT d FROM TaskDependency d "
@ -122,9 +116,12 @@ import javax.xml.bind.annotation.XmlElementWrapper;
+ "AND d.blockingTask = :blockingTask"
)
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = TaskIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = TaskIdResolver.class,
property = "uuid",
scope = Task.class
)
public class Task implements Identifiable, Serializable {
private static final long serialVersionUID = 8161343036908150426L;
@ -207,7 +204,6 @@ public class Task implements Identifiable, Serializable {
@JsonIgnore
private List<TaskDependency> blockingTasks;
/**
* Comments for the task.
*/

View File

@ -68,7 +68,8 @@ import javax.persistence.Table;
})
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "customAssignId"
resolver = TaskAssignmentIdResolver.class,
property = "uuid"
)
public class TaskAssignment implements Serializable, Exportable {

View File

@ -0,0 +1,50 @@
package org.libreccm.workflow;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class TaskAssignmentIdResolver implements ObjectIdResolver, Serializable{
private static final long serialVersionUID = 1L;
@Override
public void bindItem(final ObjectIdGenerator.IdKey id, final Object pojo) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(TaskAssignmentRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No TaskAssignment with UUID %s found in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new TaskAssignmentIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof TaskAssignmentIdResolver;
}
}

View File

@ -0,0 +1,59 @@
package org.libreccm.workflow;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class TaskAssignmentRepository
extends AbstractEntityRepository<Long, TaskAssignment> {
private static final long serialVersionUID = 1L;
@Override
public Class<TaskAssignment> getEntityClass() {
return TaskAssignment.class;
}
@Override
public String getIdAttributeName() {
return "taskAssignmentId";
}
@Override
public Long getIdOfEntity(final TaskAssignment entity) {
return entity.getTaskAssignmentId();
}
@Override
public boolean isNew(final TaskAssignment entity) {
return entity.getTaskAssignmentId() == 0;
}
public Optional<TaskAssignment> findByUuid(final String uuid) {
final TypedQuery<TaskComment> query = getEntityManager()
.createNamedQuery("TaskComment.findByUuid", TaskComment.class);
query.setParameter("uuid", uuid);
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"TaskAssignment.findByUuid",
TaskAssignment.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -54,13 +54,16 @@ import javax.persistence.Table;
@Entity
@Table(name = "WORKFLOW_TASK_COMMENTS", schema = CoreConstants.DB_SCHEMA)
@NamedQueries({
@NamedQuery(
name = "TaskComment.findByUuid",
query = "SELECT c FROM TaskComment c WHERE c.uuid = :uuid")
@NamedQuery(
name = "TaskComment.findByUuid",
query = "SELECT c FROM TaskComment c WHERE c.uuid = :uuid")
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = TaskCommentIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = TaskCommentIdResolver.class,
property = "uuid",
scope = TaskComment.class
)
public class TaskComment implements Identifiable, Serializable, Exportable {
private static final long serialVersionUID = 3842991529698351698L;
@ -179,11 +182,11 @@ public class TaskComment implements Identifiable, Serializable, Exportable {
public String toString(final String data) {
return String.format("%s{ "
+ "commentId = %d, "
+ "uuid = \"%s\""
+ "comment = \"%s\", "
+ "author = %s%s"
+ " }",
+ "commentId = %d, "
+ "uuid = \"%s\""
+ "comment = \"%s\", "
+ "author = %s%s"
+ " }",
super.toString(),
commentId,
uuid,

View File

@ -48,7 +48,8 @@ import javax.persistence.Table;
@NamedQueries({
@NamedQuery(
name = "TaskDependency.findById",
query = "SELECT d FROM TaskDependency d WHERE d.taskDependencyId = :dependencyId"
query
= "SELECT d FROM TaskDependency d WHERE d.taskDependencyId = :dependencyId"
),
@NamedQuery(
name = "TaskDependency.findByUuid",
@ -65,7 +66,8 @@ import javax.persistence.Table;
})
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid"
resolver = TaskDependencyIdResolver.class,
property = "uuid"
)
public class TaskDependency implements Serializable, Exportable {

View File

@ -0,0 +1,51 @@
package org.libreccm.workflow;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class TaskDependencyIdResolver
implements ObjectIdResolver, Serializable {
private static final long serialVersionUID = 1L;
@Override
public void bindItem(final ObjectIdGenerator.IdKey id, final Object pojo) {
// According to the Jackson JavaDoc, this method can be used to keep
// track of objects directly in a resolver implementation. We don't need
// this here therefore this method is empty.
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return CdiUtil
.createCdiUtil()
.findBean(TaskDependencyRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No TaskDependency with UUID %s found in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new TaskDependencyIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof TaskDependencyIdResolver;
}
}

View File

@ -0,0 +1,65 @@
package org.libreccm.workflow;
import org.libreccm.core.AbstractEntityRepository;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
/**
* Repository for {@link TaskDependency}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class TaskDependencyRepository
extends AbstractEntityRepository<Long, TaskDependency> {
private static final long serialVersionUID = 1L;
@Override
public Class<TaskDependency> getEntityClass() {
return TaskDependency.class;
}
@Override
public String getIdAttributeName() {
return "taskDependencyId";
}
@Override
public Long getIdOfEntity(final TaskDependency entity) {
return entity.getTaskDependencyId();
}
@Override
public boolean isNew(TaskDependency entity) {
return entity.getTaskDependencyId() == 0;
}
/**
* Finds a {@link TaskComment} by its uuid.
*
* @param uuid The uuid of the item to find
*
* @return An optional either with the found item or empty
*/
public Optional<TaskDependency> findByUuid(final String uuid) {
try {
return Optional.of(
getEntityManager()
.createNamedQuery(
"TaskDependency.findByUuid",
TaskDependency.class
)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
}

View File

@ -70,16 +70,18 @@ import org.libreccm.imexport.Exportable;
@NamedQueries({
@NamedQuery(
name = "Workflow.findByUuid",
query = "SELECT w FROM Workflow w WHERE w.uuid = :uuid")
,
query = "SELECT w FROM Workflow w WHERE w.uuid = :uuid"),
@NamedQuery(
name = "Workflow.findForObject",
query = "SELECT w FROM Workflow w "
+ "WHERE w.object = :object")
})
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = WorkflowIdResolver.class,
property = "uuid")
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = WorkflowIdResolver.class,
property = "uuid",
scope = Workflow.class
)
public class Workflow implements Identifiable, Serializable, Exportable {
private static final long serialVersionUID = 4322500264543325829L;