ObjectIdResolvers for several entities

deploy_packages_to_gitea
Jens Pelzetter 2022-09-24 17:12:14 +02:00
parent 6a9580f7a1
commit 34b81f18f9
12 changed files with 387 additions and 38 deletions

View File

@ -1,12 +1,12 @@
{ {
"name": "@librecms/ccm-cms", "name": "@librecms/ccm-cms",
"version": "7.0.0-SNAPSHOT.2022-09-24T104753", "version": "7.0.0-SNAPSHOT.2022-09-24T144715",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@librecms/ccm-cms", "name": "@librecms/ccm-cms",
"version": "7.0.0-SNAPSHOT.2022-09-24T104753", "version": "7.0.0-SNAPSHOT.2022-09-24T144715",
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@tiptap/core": "^2.0.0-beta.127", "@tiptap/core": "^2.0.0-beta.127",

View File

@ -1,6 +1,6 @@
{ {
"name": "@librecms/ccm-cms", "name": "@librecms/ccm-cms",
"version": "7.0.0-SNAPSHOT.2022-09-24T104753", "version": "7.0.0-SNAPSHOT.2022-09-24T144715",
"description": "JavaScript stuff for ccm-cms", "description": "JavaScript stuff for ccm-cms",
"main": "target/generated-resources/assets/@content-sections/cms-admin.js", "main": "target/generated-resources/assets/@content-sections/cms-admin.js",
"types": "target/generated-resources/assets/@content-sections/cms-admin.d.ts", "types": "target/generated-resources/assets/@content-sections/cms-admin.d.ts",

View File

@ -18,6 +18,9 @@
*/ */
package org.librecms.assets; package org.librecms.assets;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.annotations.Cascade; import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.CascadeType;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
@ -46,6 +49,11 @@ import static org.librecms.CmsConstants.*;
@Entity @Entity
@Audited @Audited
@Table(name = "CONTACTABLE_ENTITIES", schema = DB_SCHEMA) @Table(name = "CONTACTABLE_ENTITIES", schema = DB_SCHEMA)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = ContactableEntityIdResolver.class,
property = "uuid"
)
public class ContactableEntity extends Asset { public class ContactableEntity extends Asset {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -64,6 +72,7 @@ public class ContactableEntity extends Asset {
*/ */
@OneToOne @OneToOne
@JoinColumn(name = "POSTAL_ADDRESS_ID") @JoinColumn(name = "POSTAL_ADDRESS_ID")
@JsonIdentityReference(alwaysAsId = true)
private PostalAddress postalAddress; private PostalAddress postalAddress;
public ContactableEntity() { public ContactableEntity() {

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2022 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.librecms.assets;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.AssetRepository;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class ContactableEntityIdResolver implements Serializable,
ObjectIdResolver {
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(AssetRepository.class)
.findByUuidAndType(
id.key.toString(),
ContactableEntity.class
)
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No ContactableEntity with UUID %s found in the "
+ "database",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new ContactableEntityIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof ContactableEntityIdResolver;
}
}

View File

@ -19,6 +19,8 @@
package org.librecms.assets; package org.librecms.assets;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
import org.librecms.ui.contentsections.assets.MvcAssetEditKit; import org.librecms.ui.contentsections.assets.MvcAssetEditKit;
import org.librecms.ui.contentsections.assets.OrganizationCreateStep; import org.librecms.ui.contentsections.assets.OrganizationCreateStep;
@ -51,6 +53,11 @@ import static org.librecms.assets.AssetConstants.*;
@Entity @Entity
@Audited @Audited
@Table(name = "ORGANIZATIONS", schema = DB_SCHEMA) @Table(name = "ORGANIZATIONS", schema = DB_SCHEMA)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = OrganizationIdResolver.class,
property = "uuid"
)
public class Organization extends ContactableEntity { public class Organization extends ContactableEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2022 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.librecms.assets;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.AssetRepository;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class OrganizationIdResolver implements Serializable, ObjectIdResolver {
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(AssetRepository.class)
.findByUuidAndType(id.key.toString(), Organization.class)
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No Organization with UUID %s found in the database",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new OrganizationIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof OrganizationIdResolver;
}
}

View File

@ -19,6 +19,8 @@
package org.librecms.assets; package org.librecms.assets;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
import org.librecms.ui.contentsections.assets.MvcAssetEditKit; import org.librecms.ui.contentsections.assets.MvcAssetEditKit;
import org.librecms.ui.contentsections.assets.PersonCreateStep; import org.librecms.ui.contentsections.assets.PersonCreateStep;
@ -35,6 +37,8 @@ import javax.persistence.ElementCollection;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table; import javax.persistence.Table;
import static org.librecms.CmsConstants.*; import static org.librecms.CmsConstants.*;
@ -58,6 +62,17 @@ import static org.librecms.assets.AssetConstants.*;
createStep = PersonCreateStep.class, createStep = PersonCreateStep.class,
editStep = PersonEditStep.class editStep = PersonEditStep.class
) )
@NamedQueries(
@NamedQuery(
name = "Person.findByUuid",
query = "SELECT p FROM Person p WHERE p.uuid = :uuid"
)
)
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PersonIdResolver.class,
property = "uuid"
)
public class Person extends ContactableEntity { public class Person extends ContactableEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2022 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.librecms.assets;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PersonIdResolver implements Serializable, ObjectIdResolver {
private static final long serialVersionUID = 1L;
@Override
public void bindItem(
final ObjectIdGenerator.IdKey idKey,
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(PersonRepository.class)
.findByUuid(id.key.toString())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No Person with uuid %s found in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new PersonIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof PersonIdResolver;
}
}

View File

@ -22,19 +22,26 @@ import org.libreccm.core.AbstractEntityRepository;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
/** /**
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped @RequestScoped
public class PersonRepository extends AbstractEntityRepository<Long, Person>{ public class PersonRepository extends AbstractEntityRepository<Long, Person> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Inject
private EntityManager enityManager;
@Override @Override
public Class<Person> getEntityClass() { public Class<Person> getEntityClass() {
return Person.class; return Person.class;
@ -47,20 +54,32 @@ public class PersonRepository extends AbstractEntityRepository<Long, Person>{
@Override @Override
public Long getIdOfEntity(final Person entity) { public Long getIdOfEntity(final Person entity) {
return entity.getObjectId(); return entity.getObjectId();
} }
@Override @Override
public boolean isNew(final Person entity) { public boolean isNew(final Person entity) {
return entity.getObjectId() == 0; return entity.getObjectId() == 0;
} }
public Optional<Person> findByUuid(final String uuid) {
try {
return Optional.of(
enityManager
.createNamedQuery("Person.findByUuid", Person.class)
.setParameter("uuid", uuid)
.getSingleResult()
);
} catch (NoResultException ex) {
return Optional.empty();
}
}
public List<Person> findBySurname(final String surname) { public List<Person> findBySurname(final String surname) {
Objects.requireNonNull(surname); Objects.requireNonNull(surname);
return findAll() return findAll()
.stream() .stream()
.filter( .filter(
@ -68,5 +87,5 @@ public class PersonRepository extends AbstractEntityRepository<Long, Person>{
) )
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
} }

View File

@ -19,6 +19,8 @@
package org.librecms.assets; package org.librecms.assets;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
import org.librecms.contentsection.Asset; import org.librecms.contentsection.Asset;
import org.librecms.ui.contentsections.assets.MvcAssetEditKit; import org.librecms.ui.contentsections.assets.MvcAssetEditKit;
@ -52,6 +54,11 @@ import static org.librecms.assets.AssetConstants.ASSETS_BUNDLE;
createStep = PostalAddressCreateStep.class, createStep = PostalAddressCreateStep.class,
editStep = PostalAddressEditStep.class editStep = PostalAddressEditStep.class
) )
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
resolver = PostalAddressIdResolver.class,
property = "uuid"
)
public class PostalAddress extends Asset { public class PostalAddress extends Asset {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@ -0,0 +1,72 @@
package org.librecms.assets;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import org.libreccm.cdi.utils.CdiUtil;
import org.librecms.contentsection.AssetRepository;
import java.io.Serializable;
/*
* Copyright (C) 2022 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
*/
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class PostalAddressIdResolver implements Serializable, ObjectIdResolver {
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(AssetRepository.class)
.findByUuidAndType(id.key.toString(), PostalAddress.class)
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No PostalAddress with UUID %s found in the database.",
id.key.toString()
)
)
);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return new PostalAddressIdResolver();
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return resolverType instanceof PostalAddressIdResolver;
}
}

View File

@ -77,59 +77,48 @@ import javax.validation.constraints.NotBlank;
@NamedQueries({ @NamedQueries({
@NamedQuery( @NamedQuery(
name = "Category.topLevelCategories", name = "Category.topLevelCategories",
query = "SELECT c FROM Category c WHERE c.parentCategory IS NULL") query = "SELECT c FROM Category c WHERE c.parentCategory IS NULL"),
,
@NamedQuery( @NamedQuery(
name = "Category.findByName", name = "Category.findByName",
query = "SELECT c FROM Category c WHERE c.name = :name") query = "SELECT c FROM Category c WHERE c.name = :name"),
,
@NamedQuery( @NamedQuery(
name = "Category.findByUuid", name = "Category.findByUuid",
query = "SELECT c FROM Category c WHERE c.uuid = :uuid") query = "SELECT c FROM Category c WHERE c.uuid = :uuid"),
,
@NamedQuery( @NamedQuery(
name = "Category.findParentCategory", name = "Category.findParentCategory",
query = "SELECT c.parentCategory FROM Category c WHERE c = :category") query = "SELECT c.parentCategory FROM Category c WHERE c = :category"),
,
@NamedQuery( @NamedQuery(
name = "Category.countAssignedCategories", name = "Category.countAssignedCategories",
query = "SELECT COUNT(c) FROM Categorization c " query = "SELECT COUNT(c) FROM Categorization c "
+ "WHERE c.categorizedObject = :object" + "WHERE c.categorizedObject = :object"
) ),
,
@NamedQuery( @NamedQuery(
name = "Category.isCategorized", name = "Category.isCategorized",
query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) "
+ "FROM Categorization c " + "FROM Categorization c "
+ "WHERE c.categorizedObject = :object") + "WHERE c.categorizedObject = :object"),
,
@NamedQuery( @NamedQuery(
name = "Category.countObjects", name = "Category.countObjects",
query = "SELECT COUNT(c) FROM Categorization c " query = "SELECT COUNT(c) FROM Categorization c "
+ "WHERE c.category = :category") + "WHERE c.category = :category"),
,
@NamedQuery( @NamedQuery(
name = "Category.hasObjects", name = "Category.hasObjects",
query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) "
+ "FROM Categorization c " + "FROM Categorization c "
+ "WHERE c.category = :category") + "WHERE c.category = :category"),
,
@NamedQuery( @NamedQuery(
name = "Category.countSubCategories", name = "Category.countSubCategories",
query = "SELECT COUNT(c) FROM Category c " query = "SELECT COUNT(c) FROM Category c "
+ "WHERE c.parentCategory =:category") + "WHERE c.parentCategory =:category"),
,
@NamedQuery( @NamedQuery(
name = "Category.hasSubCategories", name = "Category.hasSubCategories",
query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) "
+ "FROM Category c " + "FROM Category c "
+ "WHERE c.parentCategory = :category") + "WHERE c.parentCategory = :category"),
,
@NamedQuery( @NamedQuery(
name = "Category.findByNameAndParent", name = "Category.findByNameAndParent",
query = "SELECT c FROM Category c " query = "SELECT c FROM Category c "
+ "WHERE c.name = :name AND c.parentCategory = :parent") + "WHERE c.name = :name AND c.parentCategory = :parent"),
,
@NamedQuery( @NamedQuery(
name = "Category.hasSubCategoryWithName", name = "Category.hasSubCategoryWithName",
query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE False END) " query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE False END) "
@ -146,9 +135,11 @@ import javax.validation.constraints.NotBlank;
) )
}) })
@XmlRootElement(name = "category", namespace = CAT_XML_NS) @XmlRootElement(name = "category", namespace = CAT_XML_NS)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, @JsonIdentityInfo(
resolver = CategoryIdResolver.class, generator = ObjectIdGenerators.PropertyGenerator.class,
property = "uuid") resolver = CategoryIdResolver.class,
property = "uuid"
)
public class Category extends CcmObject implements Serializable, Exportable { public class Category extends CcmObject implements Serializable, Exportable {
private static final long serialVersionUID = -7250208963391878547L; private static final long serialVersionUID = -7250208963391878547L;
@ -469,14 +460,14 @@ public class Category extends CcmObject implements Serializable, Exportable {
public String toString(final String data) { public String toString(final String data) {
return super.toString(String.format(", uniqueId = %s, " return super.toString(String.format(", uniqueId = %s, "
+ "name = \"%s\", " + "name = \"%s\", "
// + "title = %s, " // + "title = %s, "
+ "enabled = %b, " + "enabled = %b, "
+ "visible = %b, " + "visible = %b, "
+ "abstractCategory = %s, " + "abstractCategory = %s, "
+ "categoryOrder = %d%s", + "categoryOrder = %d%s",
uniqueId, uniqueId,
name, name,
// Objects.toString(title), // Objects.toString(title),
enabled, enabled,
visible, visible,
abstractCategory, abstractCategory,