diff --git a/ccm-cms/package-lock.json b/ccm-cms/package-lock.json index fa30844ea..da6c2a3a4 100644 --- a/ccm-cms/package-lock.json +++ b/ccm-cms/package-lock.json @@ -1,12 +1,12 @@ { "name": "@librecms/ccm-cms", - "version": "7.0.0-SNAPSHOT.2022-10-24T174909", + "version": "7.0.0-SNAPSHOT.2022-10-25T172000", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@librecms/ccm-cms", - "version": "7.0.0-SNAPSHOT.2022-10-24T174909", + "version": "7.0.0-SNAPSHOT.2022-10-25T172000", "license": "LGPL-3.0-or-later", "dependencies": { "@tiptap/core": "^2.0.0-beta.127", diff --git a/ccm-cms/package.json b/ccm-cms/package.json index 9127c0351..93e899316 100644 --- a/ccm-cms/package.json +++ b/ccm-cms/package.json @@ -1,6 +1,6 @@ { "name": "@librecms/ccm-cms", - "version": "7.0.0-SNAPSHOT.2022-10-24T174909", + "version": "7.0.0-SNAPSHOT.2022-10-25T172000", "description": "JavaScript stuff for ccm-cms", "main": "target/generated-resources/assets/@content-sections/cms-admin.js", "types": "target/generated-resources/assets/@content-sections/cms-admin.d.ts", diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/AbstractContentItemImExporter.java b/ccm-cms/src/main/java/org/librecms/contentsection/AbstractContentItemImExporter.java index d49aefaad..a51812713 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/AbstractContentItemImExporter.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/AbstractContentItemImExporter.java @@ -45,6 +45,7 @@ public abstract class AbstractContentItemImExporter final Set> entities = new HashSet<>(); entities.add(Category.class); entities.add(ContentSection.class); + entities.add(ContentType.class); return entities; } diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItem.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItem.java index d8fce0271..3f74cd096 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentItem.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentItem.java @@ -610,8 +610,8 @@ public class ContentItem extends CcmObject implements Serializable, Exportable { @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CONTENT_TYPE_ID") @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) -// @Field @XmlElement(name = "content-type", namespace = CMS_XML_NS) + @JsonIdentityReference(alwaysAsId = true) private ContentType contentType; /** diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSection.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSection.java index ffe342184..733546c46 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentSection.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentSection.java @@ -19,6 +19,7 @@ package org.librecms.contentsection; import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.libreccm.imexport.Exportable; import org.libreccm.security.RecursivePermissions; import org.libreccm.security.Role; @@ -183,6 +184,7 @@ public class ContentSection @OneToMany(mappedBy = "contentSection") @OrderBy("contentItemClass ASC") + @JsonIgnore private List contentTypes = new ArrayList<>(); @OneToMany diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java index dbeb62345..614b6d994 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java @@ -18,6 +18,9 @@ */ package org.librecms.contentsection; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import org.hibernate.annotations.NamedQueries; import org.hibernate.annotations.NamedQuery; @@ -52,6 +55,10 @@ import static org.librecms.CmsConstants.*; @Entity @Table(name = "CONTENT_TYPES", schema = DB_SCHEMA) @NamedQueries({ + @NamedQuery( + name = "ContentType.findByUuid", + query = "SELECT c FROM ContentType c WHERE c.uuid = :uuid" + ), @NamedQuery( name = "ContentType.findByContentSection", query = "SELECT c FROM ContentType c " @@ -70,6 +77,11 @@ import static org.librecms.CmsConstants.*; + "WHERE i.contentType = :type" ) }) +@JsonIdentityInfo( + generator = ObjectIdGenerators.PropertyGenerator.class, + resolver = ContentTypeIdResolver.class, + property = "uuid" +) public class ContentType extends CcmObject implements Serializable { private static final long serialVersionUID = -2708659750560382851L; @@ -79,6 +91,7 @@ public class ContentType extends CcmObject implements Serializable { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CONTENT_SECTION_ID") + @JsonIdentityReference(alwaysAsId = true) private ContentSection contentSection; @Embedded diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeIdResolver.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeIdResolver.java new file mode 100644 index 000000000..6fe305597 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeIdResolver.java @@ -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.contentsection; + +import com.fasterxml.jackson.annotation.ObjectIdGenerator; +import com.fasterxml.jackson.annotation.ObjectIdResolver; +import org.libreccm.cdi.utils.CdiUtil; + +import java.io.Serializable; +import java.util.Optional; + +import javax.enterprise.context.RequestScoped; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +public class ContentTypeIdResolver 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(ContentTypeRepository.class) + .findByUuid(id.key.toString()) + .orElseThrow( + () -> new IllegalArgumentException( + String.format( + "No ContentType with UUID %s in the database.", + id.key.toString() + ) + ) + ); + } + + @Override + public ObjectIdResolver newForDeserialization(final Object context) { + return new ContentTypeIdResolver(); + } + + @Override + public boolean canUseFor(final ObjectIdResolver resolverType) { + return resolverType instanceof ContentTypeIdResolver; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeImExporter.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeImExporter.java new file mode 100644 index 000000000..9d6816cae --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeImExporter.java @@ -0,0 +1,76 @@ +/* + * 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.contentsection; + +import org.libreccm.imexport.AbstractEntityImExporter; +import org.libreccm.imexport.Exportable; +import org.libreccm.imexport.Processes; + +import java.util.Objects; +import java.util.Set; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Processes(ContentType.class) +public class ContentTypeImExporter + extends AbstractEntityImExporter { + + @Inject + private ContentTypeRepository contentTypeRepo; + + @Override + public Class getEntityClass() { + return ContentType.class; + } + + @Override + protected Set> getRequiredEntities() { + return Set.of( + ContentSection.class + ); + } + + @Override + @Transactional(Transactional.TxType.REQUIRED) + protected void saveImportedEntity(final ContentType entity) { + contentTypeRepo.save(entity); + } + + @Override + protected ContentType reloadEntity(final ContentType entity) { + return contentTypeRepo + .findById(Objects.requireNonNull(entity).getObjectId()) + .orElseThrow( + () -> new IllegalArgumentException( + String.format( + "ContentType entity %s not found in database.", + Objects.toString(entity) + ) + ) + ); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java index 26ed3b2ef..cdc5b5704 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentTypeRepository.java @@ -70,6 +70,22 @@ public class ContentTypeRepository return type.getObjectId() == 0; } + public Optional findByUuid(final String uuid) { + try { + return Optional.of( + entityManager + .createNamedQuery( + "ContentType.findByUuid", + ContentType.class + ) + .setParameter("uuid", uuid) + .getSingleResult() + ); + } catch (NoResultException ex) { + return Optional.empty(); + } + } + public Optional findByIdAndFetchAttributes( final Long typeId, final String... fetchAttributes) { diff --git a/ccm-core/src/main/java/org/libreccm/categorization/CategoryImExporter.java b/ccm-core/src/main/java/org/libreccm/categorization/CategoryImExporter.java index f6d1b92ea..790412b08 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/CategoryImExporter.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/CategoryImExporter.java @@ -22,7 +22,6 @@ import org.libreccm.imexport.AbstractEntityImExporter; import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Processes; -import java.util.HashSet; import java.util.Objects; import java.util.Optional; import java.util.Set; diff --git a/ccm-core/src/main/java/org/libreccm/core/CcmObjectIdResolver.java b/ccm-core/src/main/java/org/libreccm/core/CcmObjectIdResolver.java index 2aa61cbb9..9988f7478 100644 --- a/ccm-core/src/main/java/org/libreccm/core/CcmObjectIdResolver.java +++ b/ccm-core/src/main/java/org/libreccm/core/CcmObjectIdResolver.java @@ -64,12 +64,12 @@ public class CcmObjectIdResolver implements Serializable, ObjectIdResolver { } @Override - public ObjectIdResolver newForDeserialization(Object context) { + public ObjectIdResolver newForDeserialization(final Object context) { return new CcmObjectIdResolver(); } @Override - public boolean canUseFor(ObjectIdResolver resolverType) { + public boolean canUseFor(final ObjectIdResolver resolverType) { return resolverType instanceof CcmObjectIdResolver; }