Refactor embedded localized string to JSON columns

Former-commit-id: 5abbc454a2
embedded-to-json
Jens Pelzetter 2020-05-17 17:07:43 +02:00
parent ff9031861f
commit a369979f79
23 changed files with 1781 additions and 1474 deletions

View File

@ -0,0 +1,104 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.contentsection.rs;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.ContentSectionRepository;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository;
import java.util.Optional;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import static javax.ws.rs.core.MediaType.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Path("/{content-section}/items/{path: .*}")
public class ContentItemController {
@Inject
private FolderRepository folderRepo;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionRepository sectionRepo;
@GET
@Path("/")
@Produces(APPLICATION_JSON)
@Transactional(Transactional.TxType.REQUIRED)
public ContentItem getContentItem(
@PathParam("content-section") final String sectionName,
@PathParam("path") final String path
) {
final String[] pathTokens = path.split("/");
final ContentSection section = sectionRepo
.findByLabel(sectionName)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"ContentSection \"%s\" does not exist.",
sectionName),
Response.Status.NOT_FOUND
)
);
final Folder rootFolder = section.getRootDocumentsFolder();
final StringBuilder folderPathBuilder = new StringBuilder("/");
Folder folder = rootFolder;
for (int i = 0; i < pathTokens.length - 1; i++) {
final String pathToken = pathTokens[i];
folderPathBuilder.append(pathToken);
final Optional<Folder> result = folder
.getSubFolders()
.stream()
.filter(subFolder -> subFolder.getName().equals(pathToken))
.findAny();
if (result.isPresent()) {
folder = result.get();
} else {
throw new WebApplicationException(
String.format(
"Folder %s not found in ContentSection %s.",
folderPathBuilder.toString(),
sectionName
)
);
}
}
final String itemName = pathTokens[pathTokens.length - 1];
final ContentItem item = itemRepo
.findByNameInFolder(folder, itemName)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"No ContentItem %s in folder %s of ContentSection %s.",
itemName,
folderPathBuilder.toString()
),
Response.Status.NOT_FOUND
)
);
return item;
}
}

View File

@ -38,6 +38,7 @@ public class ContentSectionsApplication extends Application{
classes.add(Assets.class); classes.add(Assets.class);
classes.add(ContentItems.class); classes.add(ContentItems.class);
classes.add(ContentItemController.class);
classes.add(ContentSections.class); classes.add(ContentSections.class);
classes.add(Images.class); classes.add(Images.class);

View File

@ -0,0 +1,354 @@
/*
* Copyright (C) 2020 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 db.migrations.org.libreccm.ccm_core.pgsql;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import javax.json.Json;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class V7_0_0_37__localized_string_embedded_to_json extends BaseJavaMigration {
private static final String[] ADD_COLUMN_STATEMENTS = new String[]{
"alter table CCM_CORE.CATEGORIES add column TITLE jsonb",
"alter table CCM_CORE.CATEGORIES add column DESCRIPTION jsonb",
"alter table CCM_CORE.CATEGORY_DOMAINS add column DESCRIPTION jsonb",
"alter table CCM_CORE.CATEGORY_DOMAINS add column TITLE jsonb",
"alter table CCM_ROLES add column DESCRIPTION jsonb",
"alter table CCM_CORE.FORMBUILDER_COMPONENTS add column DESCRIPTION jsonb",
"alter table CCM_CORE.FORMBUILDER_DATA_QUERIES add column DESCRIPTION jsonb",
"alter table CCM_CORE.FORMBUILDER_DATA_QUERIES add column QUERY_NAME jsonb",
"alter table CCM_CORE.FORMBUILDER_OPTIONS add column LABEL jsonb",
"alter table CCM_CORE.FORMBUILDER_PROCESS_LISTENERS add column DESCRIPTION jsonb",
"alter table CCM_CORE.FORMBUILDER_PROCESS_LISTENERS add column LISTENER_NAME jsonb",
"alter table CCM_CORE.PAGE_MODELS add column DESCRIPTION jsonb",
"alter table CCM_CORE.PAGE_MODELS add column TITLE jsonb",
"alter table CCM_CORE.RESOURCE_TYPES add column DESCRIPTION jsonb",
"alter table CCM_CORE.RESOURCES add column DESCRIPTION jsonb",
"alter table CCM_CORE.RESOURCES add column TITLE jsonb",
"alter table CCM_CORE.SETTINGS add column SETTING_VALUE_LOCALIZED_STRING jsonb",
"alter table CCM_CORE.WORKFLOW_TASKS add column DESCRIPTION jsonb",
"alter table CCM_CORE.WORKFLOW_TASKS add column LABEL jsonb",
"alter table CCM_CORE.WORKFLOWS add column DESCRIPTION jsonb",
"alter table CCM_CORE.WORKFLOWS add column NAME jsonb"
};
private static final int OBJECT_TABLE = 0;
private static final int LOCALIZED_STR_TABLE = 1;
private static final int OBJECT_ID_COL = 2;
private static final int VALUE_ID_COL = 3;
private static final int TARGET_COL = 4;
private static final String[][] MIGRATE = new String[][]{
new String[]{
"CCM_CORE.CATEGORIES",
"CCM_CORE.CATEGORY_TITLES",
"OBJECT_ID",
"OBJECT_ID",
"TITLE"
},
new String[]{
"CCM_CORE.CATEGORIES",
"CCM_CORE.CATEGORY_DESCRIPTIONS",
"OBJECT_ID",
"OBJECT_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.CATEGORY_DOMAINS",
"CCM_CORE.DOMAIN_TITLES",
"OBJECT_ID",
"OBJECT_ID",
"TITLE"
},
new String[]{
"CCM_CORE.CATEGORY_DOMAINS",
"CCM_CORE.DOMAIN_DESCRIPTIONS",
"OBJECT_ID",
"OBJECT_ID",
"DESCRIPTIONS"
},
new String[]{
"CCM_CORE.CCM_ROLES",
"CCM_CORE.ROLE_DESCRIPTIONS",
"ROLE_ID",
"ROLE_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.FORMBUILDER_COMPONENTS",
"CCM_CORE.FORMBUILDER_COMPONENT_DESCRIPTIONS",
"OBJECT_ID",
"OBJECT_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.FORMBUILDER_DATA_QUERIES",
"FORMBUILDER_DATA_QUERY_DESCRIPTIONS",
"OBJECT_ID",
"OBJECT_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.FORMBUILDER_DATA_QUERIES",
"FORMBUILDER_DATA_QUERY_NAMES",
"OBJECT_ID",
"OBJECT_ID",
"QUERY_NAME"
},
new String[]{
"CCM_CORE.FORMBUILDER_OPTIONS",
"FORMBUILDER_OPTION_LABELS",
"OBJECT_ID",
"OBJECT_ID",
"LABEL"
},
new String[]{
"CCM_CORE.FORMBUILDER_PROCESS_LISTENERS",
"FORMBUILDER_LISTENER_DESCRIPTIONS",
"OBJECT_ID",
"OBJECT_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.FORMBUILDER_PROCESS_LISTENERS",
"FORMBUILDER_LISTENER_NAMES",
"OBJECT_ID",
"OBJECT_ID",
"LISTENER_NAME"
},
new String[]{
"CCM_CORE.PAGE_MODELS",
"CCM_CORE.PAGE_MODEL_DESCRIPTIONS",
"PAGE_MODEL_ID",
"PAGE_MODEL_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.PAGE_MODELS",
"CCM_CORE.PAGE_MODEL_TITLES",
"PAGE_MODEL_ID",
"PAGE_MODEL_ID",
"TITLE"
},
new String[]{
"CCM_CORE.RESOURCE_TYPES",
"CCM_CORE.RESOURCE_TYPE_DESCRIPTIONS",
"RESOURCE_TYPE_ID",
"RESOURCE_TYPE_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.RESOURCES",
"CCM_CORE.RESOURCE_DESCRIPTIONS",
"OBJECT_ID", "OBJECT_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.RESOURCES",
"CCM_CORE.RESOURCE_TITLES",
"OBJECT_ID",
"OBJECT_ID",
"TITLE"
},
new String[]{
"CCM_CORE.SETTINGS",
"CCM_CORE.SETTINGS_L10N_STR_VALUES",
"SETTING_ID",
"ENTRY_ID",
"SETTING_VALUE_LOCALIZED_STRING"
},
new String[]{
"CCM_CORE.WORKFLOW_TASKS",
"CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS",
"TASK_ID",
"TASK_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.WORKFLOW_TASKS",
"CCM_CORE.WORKFLOW_TASK_LABELS",
"TASK_ID",
"TASK_ID",
"LABEL"
},
new String[]{
"CCM_CORE.WORKFLOWS",
"CCM_CORE.WORKFLOW_DESCRIPTIONS",
"WORKFLOW_ID",
"WORKFLOW_ID",
"DESCRIPTION"
},
new String[]{
"CCM_CORE.WORKFLOWS",
"CCM_CORE.WORKFLOW_NAMES",
"WORKFLOW_ID",
"WORKFLOW_ID",
"NAME"
}
};
private static final String SELECT_IDS_QUERY_TEMPLATE = "select %s from %s";
private static final String SELECT_VALUES_QUERY_TEMPLATE
= "select locale, localized_value from %s where %s = ?";
private static final String SET_VALUES_QUERY_TEMPLATE
= "update %s set %s = ? where %s = ?";
private static final String[] DROP_TABLES = new String[]{
"CCM_CORE.CATEGORY_TITLES",
"CCM_CORE.CATEGORY_DESCRIPTIONS",
"CCM_CORE.DOMAIN_TITLES",
"CCM_CORE.DOMAIN_DESCRIPTIONS",
"CCM_CORE.ROLE_DESCRIPTIONS",
"CCM_CORE.FORMBUILDER_COMPONENT_DESCRIPTIONS",
"FORMBUILDER_DATA_QUERY_DESCRIPTIONS",
"FORMBUILDER_DATA_QUERY_NAMES",
"FORMBUILDER_OPTION_LABELS",
"FORMBUILDER_LISTENER_DESCRIPTIONS",
"FORMBUILDER_LISTENER_NAMES",
"CCM_CORE.PAGE_MODEL_DESCRIPTIONS",
"CCM_CORE.PAGE_MODEL_TITLES",
"CCM_CORE.RESOURCE_TYPE_DESCRIPTIONS",
"CCM_CORE.RESOURCE_DESCRIPTIONS",
"CCM_CORE.RESOURCE_TITLES",
"CCM_CORE.SETTINGS_L10N_STR_VALUES",
"CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS",
"CCM_CORE.WORKFLOW_TASK_LABELS",
"CCM_CORE.WORKFLOW_DESCRIPTIONS",
"CCM_CORE.WORKFLOW_NAMES",};
private static final String DROP_TABLES_QUERY_TEMPLATE = "drop table %s";
@Override
public void migrate(final Context context) throws Exception {
final Connection connection = context.getConnection();
// Add columns for localized strings
for (final String addColStatement : ADD_COLUMN_STATEMENTS) {
try (PreparedStatement statement = connection.prepareStatement(
addColStatement
)) {
statement.execute();
}
}
for (final String[] migrate : MIGRATE) {
final String objectTable = migrate[OBJECT_TABLE];
final String localizedStringTable = migrate[LOCALIZED_STR_TABLE];
final String objectIdCol = migrate[OBJECT_ID_COL];
final String valueIdCol = migrate[VALUE_ID_COL];
final String targetCol = migrate[TARGET_COL];
final List<Long> objectIds = new ArrayList<>();
final String selectIdsQuerySql = String.format(
SELECT_IDS_QUERY_TEMPLATE,
objectIdCol,
objectTable
);
try (PreparedStatement stmt = connection.prepareStatement(
selectIdsQuerySql
);
ResultSet resultSet = stmt.executeQuery()) {
while (resultSet.next()) {
objectIds.add(resultSet.getLong(objectIdCol));
}
}
final String valuesQuerySql = String.format(
SELECT_VALUES_QUERY_TEMPLATE,
localizedStringTable,
valueIdCol
);
final String setValuesQuerySql = String.format(
SET_VALUES_QUERY_TEMPLATE,
objectTable,
targetCol,
objectIdCol
);
try (PreparedStatement selectValuesStmt = connection
.prepareStatement(valuesQuerySql);
PreparedStatement setValuesStmt = connection.prepareStatement(
setValuesQuerySql
)) {
for (final Long objectId : objectIds) {
selectValuesStmt.setLong(1, objectId);
final JsonObjectBuilder jsonObjBuilder = Json
.createObjectBuilder();
try (ResultSet resultSet = selectValuesStmt.executeQuery()) {
while (resultSet.next()) {
final String locale = resultSet.getString(
"locale"
);
final String localizedValue = resultSet.getString(
"localizedValue"
);
jsonObjBuilder.add(locale, localizedValue);
}
}
try (StringWriter strWriter = new StringWriter();
JsonWriter jsonWriter = Json.createWriter(strWriter)) {
jsonWriter.writeObject(jsonObjBuilder.build());
setValuesStmt.setString(1, strWriter.toString());
}
setValuesStmt.setLong(2, objectId);
setValuesStmt.execute();
setValuesStmt.clearParameters();
selectValuesStmt.clearParameters();
}
}
for (final String dropTable : DROP_TABLES) {
try(PreparedStatement stmt = connection.prepareStatement(
String.format(DROP_TABLES_QUERY_TEMPLATE, dropTable)
)) {
stmt.execute();
}
}
// SELECT object_id FROM ... order by object_id;
// for all object_id SELECT locale, localized_value FROM ... WHERE object_id = :object_id
// build json
// INSERT INTO ... WHERE object_id = :object_id
// Drop tables
}
}
}

View File

@ -40,6 +40,7 @@ import java.util.Objects;
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS; import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
import javax.persistence.AssociationOverride; import javax.persistence.AssociationOverride;
@ -77,59 +78,48 @@ import javax.persistence.Table;
@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) "
@ -174,28 +164,32 @@ public class Category extends CcmObject implements Serializable, Exportable {
/** /**
* The human readable and localisable title of the category. * The human readable and localisable title of the category.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "CATEGORY_TITLES", // joinTable = @JoinTable(name = "CATEGORY_TITLES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")} // @JoinColumn(name = "OBJECT_ID")}
)) // ))
@Column(name = "TITLE")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
@XmlElement(name = "title", namespace = CAT_XML_NS) @XmlElement(name = "title", namespace = CAT_XML_NS)
private LocalizedString title; private LocalizedString title;
/** /**
* A localisable description of the category. * A localisable description of the category.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "CATEGORY_DESCRIPTIONS", // joinTable = @JoinTable(name = "CATEGORY_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")} // @JoinColumn(name = "OBJECT_ID")}
)) // ))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
@XmlElement(name = "description", namespace = CAT_XML_NS) @XmlElement(name = "description", namespace = CAT_XML_NS)
private LocalizedString description; private LocalizedString description;
@ -469,14 +463,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,

View File

@ -142,9 +142,10 @@ public class CategoryTreeModelLite implements TreeModel {
return category.getName(); return category.getName();
} else { } else {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryTreeModelLiteController controller = cdiUtil final GlobalizationHelper globalizationHelper = cdiUtil
.findBean(CategoryTreeModelLiteController.class); .findBean(GlobalizationHelper.class);
return controller.getTitle(category); return globalizationHelper
.getValueFromLocalizedString(category.getTitle());
} }
} }

View File

@ -40,6 +40,7 @@ import java.io.Serializable;
import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS; import static org.libreccm.categorization.CategorizationConstants.CAT_XML_NS;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
import java.util.ArrayList; import java.util.ArrayList;
@ -160,26 +161,30 @@ public class Domain extends CcmObject implements Serializable, Exportable {
* A human readable title for the {@code Domain}. The title can be * A human readable title for the {@code Domain}. The title can be
* localised. * localised.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "DOMAIN_TITLES", // joinTable = @JoinTable(name = "DOMAIN_TITLES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")})) // @JoinColumn(name = "OBJECT_ID")}))
@Column(name = "TITLE")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
@XmlElement(name = "title", namespace = CAT_XML_NS) @XmlElement(name = "title", namespace = CAT_XML_NS)
private LocalizedString title; private LocalizedString title;
/** /**
* A description of the domain. The description can be localised. * A description of the domain. The description can be localised.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "DOMAIN_DESCRIPTIONS", // joinTable = @JoinTable(name = "DOMAIN_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")})) // @JoinColumn(name = "OBJECT_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
@XmlElement(name = "description", namespace = CAT_XML_NS) @XmlElement(name = "description", namespace = CAT_XML_NS)
private LocalizedString description; private LocalizedString description;

View File

@ -23,13 +23,10 @@ import org.libreccm.l10n.LocalizedString;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import org.hibernate.annotations.Type;
import javax.persistence.AssociationOverride; import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
/** /**
* A setting which stores a {@link LocalizedString} . This can be used for * A setting which stores a {@link LocalizedString} . This can be used for
@ -44,13 +41,15 @@ public class LocalizedStringSetting
private static final long serialVersionUID = 667750736151545279L; private static final long serialVersionUID = 667750736151545279L;
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "SETTINGS_L10N_STR_VALUES", // joinTable = @JoinTable(name = "SETTINGS_L10N_STR_VALUES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "ENTRY_ID")})) // @JoinColumn(name = "ENTRY_ID")}))
@Column(name = "SETTING_VALUE_LOCALIZED_STRING")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString value; private LocalizedString value;
public LocalizedStringSetting() { public LocalizedStringSetting() {

View File

@ -29,6 +29,7 @@ import java.io.Serializable;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
import java.util.ArrayList; import java.util.ArrayList;
@ -82,25 +83,29 @@ public class Resource extends CcmObject implements Serializable, Exportable {
/** /**
* A localisable title for the {@code Resource}. * A localisable title for the {@code Resource}.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "RESOURCE_TITLES", // joinTable = @JoinTable(name = "RESOURCE_TITLES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")})) // @JoinColumn(name = "OBJECT_ID")}))
@Column(name = "TITLE")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString title; private LocalizedString title;
/** /**
* A localisable description for the {@code Resource}. * A localisable description for the {@code Resource}.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "RESOURCE_DESCRIPTIONS", // joinTable = @JoinTable(name = "RESOURCE_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OBJECT_ID")})) // @JoinColumn(name = "OBJECT_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
@ManyToOne @ManyToOne

View File

@ -27,17 +27,14 @@ import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
import javax.persistence.AssociationOverride;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.Table; import javax.persistence.Table;
@ -87,13 +84,15 @@ public class ResourceType implements Serializable, Exportable {
@Column(name = "TITLE", length = 254, nullable = false) @Column(name = "TITLE", length = 254, nullable = false)
private String title; private String title;
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "RESOURCE_TYPE_DESCRIPTIONS", // joinTable = @JoinTable(name = "RESOURCE_TYPE_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "RESOURCE_TYPE_ID")})) // @JoinColumn(name = "RESOURCE_TYPE_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
@Column(name = "WORKSPACE_APP") @Column(name = "WORKSPACE_APP")

View File

@ -21,7 +21,6 @@ package org.libreccm.formbuilder;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -29,6 +28,14 @@ import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
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>
@ -46,13 +53,15 @@ public class Component extends CcmObject implements Serializable {
@Column(name = "ADMIN_NAME") @Column(name = "ADMIN_NAME")
private String adminName; private String adminName;
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "FORMBUILDER_COMPONENT_DESCRIPTIONS", // joinTable = @JoinTable(name = "FORMBUILDER_COMPONENT_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "COMPONENT_ID")})) // @JoinColumn(name = "COMPONENT_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
@Column(name = "ATTRIBUTE_STRING") @Column(name = "ATTRIBUTE_STRING")

View File

@ -20,12 +20,17 @@ package org.libreccm.formbuilder;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import javax.persistence.Column;
import javax.persistence.Entity;
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>
@ -39,12 +44,14 @@ public class Option extends Component implements Serializable {
@Column(name = "PARAMETER_VALUE") @Column(name = "PARAMETER_VALUE")
private String parameterValue; private String parameterValue;
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "FORMBUILDER_OPTION_LABELS", // joinTable = @JoinTable(name = "FORMBUILDER_OPTION_LABELS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "OPTION_ID")})) // @JoinColumn(name = "OPTION_ID")}))
@Column(name = "LABEL")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString label; private LocalizedString label;
public String getParameterValue() { public String getParameterValue() {

View File

@ -21,12 +21,20 @@ package org.libreccm.formbuilder;
import org.libreccm.core.CcmObject; import org.libreccm.core.CcmObject;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import javax.persistence.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import javax.persistence.AssociationOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
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>
@ -40,22 +48,26 @@ public class PersistentDataQuery extends CcmObject implements Serializable {
@Column(name = "QUERY_ID") @Column(name = "QUERY_ID")
private String queryId; private String queryId;
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable( // joinTable = @JoinTable(
name = "FORMBUILDER_DATA_QUERY_NAMES", // name = "FORMBUILDER_DATA_QUERY_NAMES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "DATA_QUERY_ID")})) // @JoinColumn(name = "DATA_QUERY_ID")}))
@Column(name = "QUERY_NAME")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString name; private LocalizedString name;
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable( // joinTable = @JoinTable(
name = "FORMBUILDER_DATA_QUERY_DESCRIPTIONS", // name = "FORMBUILDER_DATA_QUERY_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "DATA_QUERY_ID")})) // @JoinColumn(name = "DATA_QUERY_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
public PersistentDataQuery() { public PersistentDataQuery() {

View File

@ -26,11 +26,10 @@ import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import javax.persistence.AssociationOverride; import org.hibernate.annotations.Type;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
@ -44,23 +43,26 @@ public class ProcessListener extends CcmObject implements Serializable {
private static final long serialVersionUID = -3029184333026605708L; private static final long serialVersionUID = -3029184333026605708L;
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable( // joinTable = @JoinTable(
name = "FORMBUILDER_PROCESS_LISTENER_NAMES", // name = "FORMBUILDER_PROCESS_LISTENER_NAMES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "PROCESS_LISTENER_ID")})) // @JoinColumn(name = "PROCESS_LISTENER_ID")}))
@Column(name = "LISTENER_NAME")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString name; private LocalizedString name;
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable( // joinTable = @JoinTable(
name = "FORMBUILDER_PROCESS_LISTENER_DESCRIPTIONS", // name = "FORMBUILDER_PROCESS_LISTENER_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "PROCESS_LISTENER_ID")})) // @JoinColumn(name = "PROCESS_LISTENER_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
@Column(name = "LISTENER_CLASS") @Column(name = "LISTENER_CLASS")
@ -77,7 +79,7 @@ public class ProcessListener extends CcmObject implements Serializable {
name = new LocalizedString(); name = new LocalizedString();
description = new LocalizedString(); description = new LocalizedString();
} }
public LocalizedString getName() { public LocalizedString getName() {
return name; return name;
} }

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2020 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.hibernate.dialects;
import org.hibernate.dialect.H2Dialect;
import java.sql.Types;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LibreCcmH2Dialect extends H2Dialect {
public LibreCcmH2Dialect() {
super();
super.registerColumnType(Types.JAVA_OBJECT, "json");
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2020 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.hibernate.dialects;
import org.hibernate.dialect.PostgreSQL9Dialect;
import java.sql.Types;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LibreCcmPgSql9Dialect extends PostgreSQL9Dialect {
public LibreCcmPgSql9Dialect() {
super();
super.registerColumnType(Types.JAVA_OBJECT, "jsonb");
}
}

View File

@ -19,22 +19,14 @@
package org.libreccm.l10n; package org.libreccm.l10n;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Type;
import org.hibernate.search.annotations.Field;
import org.libreccm.l10n.jaxb.LocalizedStringValuesAdapter; import org.libreccm.l10n.jaxb.LocalizedStringValuesAdapter;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.MapKeyColumn;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -45,6 +37,10 @@ import java.util.Set;
import static org.libreccm.l10n.L10NConstants.L10N_XML_NS; import static org.libreccm.l10n.L10NConstants.L10N_XML_NS;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
/** /**
* A helper class for localisable string properties. This class is declared as * A helper class for localisable string properties. This class is declared as
* embeddable, so that it can be used in every other entity. The localised * embeddable, so that it can be used in every other entity. The localised
@ -53,7 +49,7 @@ import static org.libreccm.l10n.L10NConstants.L10N_XML_NS;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@Embeddable //@Embeddable
@XmlRootElement(name = "localized-string", namespace = L10N_XML_NS) @XmlRootElement(name = "localized-string", namespace = L10N_XML_NS)
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class LocalizedString implements Serializable { public class LocalizedString implements Serializable {
@ -63,13 +59,13 @@ public class LocalizedString implements Serializable {
/** /**
* The localised values of the string. * The localised values of the string.
*/ */
@ElementCollection(fetch = FetchType.LAZY) // @ElementCollection(fetch = FetchType.LAZY)
@MapKeyColumn(name = "LOCALE") // @MapKeyColumn(name = "LOCALE")
@Column(name = "LOCALIZED_VALUE") // @Column(name = "LOCALIZED_VALUE")
@Basic // @Basic
@Lob // @Lob
@Type(type = "org.hibernate.type.TextType") // @Type(type = "org.hibernate.type.TextType")
@Field // @Field
@XmlElement(name = "values", namespace = L10N_XML_NS) @XmlElement(name = "values", namespace = L10N_XML_NS)
@XmlJavaTypeAdapter(LocalizedStringValuesAdapter.class) @XmlJavaTypeAdapter(LocalizedStringValuesAdapter.class)
private Map<Locale, String> values; private Map<Locale, String> values;
@ -202,6 +198,41 @@ public class LocalizedString implements Serializable {
return obj instanceof LocalizedString; return obj instanceof LocalizedString;
} }
public static LocalizedString fromJson(final JsonObject jsonObject) {
final LocalizedString localizedString = new LocalizedString();
jsonObject
.entrySet()
.stream()
.forEach(
entry -> localizedString.addValue(
new Locale(entry.getKey()),
jsonObject.getString(entry.getKey())
)
);
return localizedString;
}
public JsonObjectBuilder buildJson() {
final JsonObjectBuilder builder = Json.createObjectBuilder();
values
.entrySet()
.stream()
.forEach(
entry -> builder.add(
entry.getKey().toString(), entry.getValue()
)
);
return builder;
}
public JsonObject toJson() {
return buildJson().build();
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@ -0,0 +1,155 @@
/*
* Copyright (C) 2020 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.l10n;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonWriter;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LocalizedStringType implements UserType {
@Override
public int[] sqlTypes() {
return new int[]{Types.JAVA_OBJECT};
}
@Override
public Class<LocalizedString> returnedClass() {
return LocalizedString.class;
}
@Override
public boolean equals(final Object obj1, final Object obj2)
throws HibernateException {
return Objects.equals(obj1, obj2);
}
@Override
public int hashCode(final Object obj) throws HibernateException {
return Objects.hashCode(obj);
}
@Override
public Object nullSafeGet(
final ResultSet resultSet,
final String[] names,
final SharedSessionContractImplementor session,
final Object owner
) throws HibernateException, SQLException {
final String cellContent = resultSet.getString(names[0]);
if (cellContent == null) {
return null;
}
return LocalizedString.fromJson(
Json.createReader(new StringReader(cellContent)).readObject()
);
}
@Override
public void nullSafeSet(
final PreparedStatement statement,
final Object value,
final int index,
final SharedSessionContractImplementor session
) throws HibernateException, SQLException {
final JsonObject jsonObject = ((LocalizedString) value).toJson();
try (StringWriter strWriter = new StringWriter();
JsonWriter jsonWriter = Json.createWriter(strWriter)) {
jsonWriter.writeObject(jsonObject);
statement.setObject(index, strWriter.toString(), Types.OTHER);
} catch (IOException ex) {
throw new HibernateException(ex);
}
}
@Override
public Object deepCopy(final Object value) throws HibernateException {
final byte[] serialized;
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(value);
oos.flush();
serialized = bos.toByteArray();
} catch (IOException ex) {
throw new HibernateException(ex);
}
final Object obj;
try (final ByteArrayInputStream bais = new ByteArrayInputStream(
serialized
);
final ObjectInputStream ois = new ObjectInputStream(bais);) {
obj = ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
throw new HibernateException(ex);
}
return obj;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(final Object value)
throws HibernateException {
return (Serializable) deepCopy(value);
}
@Override
public Object assemble(final Serializable cached, final Object owner) throws
HibernateException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object replace(
final Object original,
final Object target,
final Object owner
) throws HibernateException {
return deepCopy(original);
}
}

View File

@ -18,6 +18,7 @@
*/ */
package org.libreccm.pagemodel; package org.libreccm.pagemodel;
import org.hibernate.annotations.Type;
import org.libreccm.core.CoreConstants; import org.libreccm.core.CoreConstants;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import org.libreccm.web.CcmApplication; import org.libreccm.web.CcmApplication;
@ -225,27 +226,31 @@ public class PageModel implements Serializable {
* The localised title of this {@code PageModel} (shown in the * The localised title of this {@code PageModel} (shown in the
* administration UI), * administration UI),
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "PAGE_MODEL_TITLES", // joinTable = @JoinTable(name = "PAGE_MODEL_TITLES",
schema = CoreConstants.DB_SCHEMA, // schema = CoreConstants.DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "PAGE_MODEL_ID") // @JoinColumn(name = "PAGE_MODEL_ID")
})) // }))
@Column(name = "TITLE")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString title; private LocalizedString title;
/** /**
* A description of this {@code PageModel} describing its purpose. * A description of this {@code PageModel} describing its purpose.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "PAGE_MODEL_DESCRIPTIONS", // joinTable = @JoinTable(name = "PAGE_MODEL_DESCRIPTIONS",
schema = CoreConstants.DB_SCHEMA, // schema = CoreConstants.DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "PAGE_MODEL_ID") // @JoinColumn(name = "PAGE_MODEL_ID")
})) // }))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
/** /**

View File

@ -29,6 +29,7 @@ import org.libreccm.workflow.TaskAssignment;
import static org.libreccm.core.CoreConstants.CORE_XML_NS; import static org.libreccm.core.CoreConstants.CORE_XML_NS;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
import java.io.Serializable; import java.io.Serializable;
@ -182,14 +183,16 @@ public class Role implements Serializable, Exportable {
/** /**
* An optional description for a role. * An optional description for a role.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "ROLE_DESCRIPTIONS", // joinTable = @JoinTable(name = "ROLE_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "ROLE_ID") // @JoinColumn(name = "ROLE_ID")
})) // }))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
@XmlElement(name = "description", namespace = CORE_XML_NS) @XmlElement(name = "description", namespace = CORE_XML_NS)
private LocalizedString description = new LocalizedString(); private LocalizedString description = new LocalizedString();

View File

@ -36,6 +36,8 @@ import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import javax.persistence.AssociationOverride; import javax.persistence.AssociationOverride;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Embedded; import javax.persistence.Embedded;
@ -147,25 +149,29 @@ public class Task implements Identifiable, Serializable {
/** /**
* A human readable, localisable label for the task. * A human readable, localisable label for the task.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "WORKFLOW_TASK_LABELS", // joinTable = @JoinTable(name = "WORKFLOW_TASK_LABELS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "TASK_ID")})) // @JoinColumn(name = "TASK_ID")}))
@Column(name = "LABEL")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString label; private LocalizedString label;
/** /**
* A description of the task. * A description of the task.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "WORKFLOW_TASK_DESCRIPTIONS", // joinTable = @JoinTable(name = "WORKFLOW_TASK_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "TASK_ID")})) // @JoinColumn(name = "TASK_ID")}))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description; private LocalizedString description;
/** /**

View File

@ -56,6 +56,7 @@ import java.util.Objects;
import static org.libreccm.core.CoreConstants.DB_SCHEMA; import static org.libreccm.core.CoreConstants.DB_SCHEMA;
import org.hibernate.annotations.Type;
import org.libreccm.imexport.Exportable; import org.libreccm.imexport.Exportable;
/** /**
@ -116,26 +117,30 @@ public class Workflow implements Identifiable, Serializable, Exportable {
/** /**
* Human readable name of the workflow. * Human readable name of the workflow.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "WORKFLOW_NAMES", // joinTable = @JoinTable(name = "WORKFLOW_NAMES",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "WORKFLOW_ID")})) // @JoinColumn(name = "WORKFLOW_ID")}))
@Column(name = "NAME")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString name = new LocalizedString(); private LocalizedString name = new LocalizedString();
/** /**
* Description of the workflow. * Description of the workflow.
*/ */
@Embedded // @Embedded
@AssociationOverride( // @AssociationOverride(
name = "values", // name = "values",
joinTable = @JoinTable(name = "WORKFLOW_DESCRIPTIONS", // joinTable = @JoinTable(name = "WORKFLOW_DESCRIPTIONS",
schema = DB_SCHEMA, // schema = DB_SCHEMA,
joinColumns = { // joinColumns = {
@JoinColumn(name = "WORKFLOW_ID") // @JoinColumn(name = "WORKFLOW_ID")
})) // }))
@Column(name = "DESCRIPTION")
@Type(type = "org.libreccm.l10n.LocalizedStringType")
private LocalizedString description = new LocalizedString(); private LocalizedString description = new LocalizedString();
/** /**