diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java
new file mode 100644
index 000000000..2698538ed
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItem.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 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.pagemodel;
+
+import org.libreccm.categorization.Category;
+import org.libreccm.pagemodel.ComponentModel;
+import org.libreccm.pagemodel.PageModel;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.Table;
+
+import static org.librecms.CmsConstants.*;
+
+/**
+ * A {@link PageModel} component model for displaying the Greeting/Index item of
+ * a {@link Category}.
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Table(name = "GREETING_ITEMS", schema = DB_SCHEMA)
+public class GreetingItem extends ComponentModel {
+
+ private static final long serialVersionUID = -5509783666595294223L;
+
+ @ElementCollection
+ @CollectionTable(name = "GREETING_ITEM_INCLUDED_PATHS",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "GREETING_ITEM_ID")
+ })
+ private Set includedPropertyPaths;
+
+ @ElementCollection
+ @CollectionTable(name = "GREETING_ITEM_EXCLUDED_PATHS",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "GREETING_ITEM_ID")
+ })
+ private Set excludedProperties;
+
+ public GreetingItem() {
+ includedPropertyPaths = new HashSet<>();
+ excludedProperties = new HashSet<>();
+ }
+
+ public Set getIncludedPropertyPaths() {
+ return Collections.unmodifiableSet(includedPropertyPaths);
+ }
+
+ protected void setIncludedPropertyPaths(
+ final Set includePropertyPaths) {
+ this.includedPropertyPaths = new HashSet<>(includePropertyPaths);
+ }
+
+ public void addIncludedPropertyPath(final String path) {
+ includedPropertyPaths.add(path);
+ }
+
+ public void removeIncludedPropertyPath(final String path) {
+ includedPropertyPaths.remove(path);
+ }
+
+ public Set getExcludedPropertyPaths() {
+ return Collections.unmodifiableSet(excludedProperties);
+ }
+
+ protected void setExcludedPropertyPaths(
+ final Set excludedProperties) {
+ this.excludedProperties = new HashSet<>(excludedProperties);
+ }
+
+ public void addExcludedProperty(final String path) {
+ excludedProperties.add(path);
+ }
+
+ public void removeExcludedProperty(final String path) {
+ excludedProperties.remove(path);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 13 * hash + Objects.hashCode(includedPropertyPaths);
+ hash = 13 * hash + Objects.hashCode(excludedProperties);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (!(obj instanceof GreetingItem)) {
+ return false;
+ }
+ final GreetingItem other = (GreetingItem) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (!Objects.equals(includedPropertyPaths,
+ other.getIncludedPropertyPaths())) {
+ return false;
+ }
+ return Objects.equals(excludedProperties,
+ other.getExcludedPropertyPaths());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+ return obj instanceof GreetingItem;
+ }
+
+ @Override
+ public String toString(final String data) {
+ return super.toString(String
+ .format(", includedPropertyPaths = %s, "
+ + "excludedProperties = %s%s",
+ Objects.toString(includedPropertyPaths),
+ Objects.toString(excludedProperties),
+ data));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java
new file mode 100644
index 000000000..b90b41e42
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/pagemodel/GreetingItemBuilder.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2017 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.pagemodel;
+
+import org.libreccm.categorization.Category;
+import org.libreccm.categorization.CategoryManager;
+import org.libreccm.categorization.CategoryRepository;
+import org.libreccm.core.CcmObject;
+import org.libreccm.core.UnexpectedErrorException;
+import org.libreccm.l10n.GlobalizationHelper;
+import org.libreccm.pagemodel.ComponentBuilder;
+import org.libreccm.pagemodel.ComponentModelType;
+import org.libreccm.security.PermissionChecker;
+import org.librecms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItemL10NManager;
+import org.librecms.contentsection.ContentItemManager;
+import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.contentsection.privileges.ItemPrivileges;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.transaction.Transactional;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import static org.librecms.pages.PagesConstants.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@ComponentModelType(componentModel = GreetingItem.class)
+public class GreetingItemBuilder implements ComponentBuilder {
+
+ @Inject
+ private GlobalizationHelper globalizationHelper;
+
+ @Inject
+ private CategoryRepository categoryRepo;
+
+ @Inject
+ private ContentItemL10NManager iteml10nManager;
+
+ @Inject
+ private CategoryManager categoryManager;
+
+ @Inject
+ private ContentItemManager itemManager;
+
+ @Inject
+ private ContentItemRepository itemRepo;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ @Transactional(Transactional.TxType.REQUIRED)
+ @Override
+ public Map buildComponent(
+ final GreetingItem componentModel,
+ final Map parameters) {
+
+ Objects.requireNonNull(componentModel);
+ Objects.requireNonNull(parameters);
+
+ if (!parameters.containsKey(PARAMETER_CATEGORY)) {
+ throw new IllegalArgumentException("The parameters map passed to "
+ + "this GreetingItem component does not include the parameter "
+ + "\"category\"");
+ }
+
+ if (!(parameters.get(PARAMETER_CATEGORY) instanceof Category)) {
+ throw new IllegalArgumentException(String
+ .format("The parameters map passed to "
+ + "this GreetingItem component contains the parameter "
+ + "\"category\", but the parameter is not of type"
+ + "\"%s\" but of type \"%s\".",
+ Category.class.getName(),
+ parameters.get(PARAMETER_CATEGORY).getClass().getName()));
+ }
+
+ final Category category = categoryRepo
+ .findById(((CcmObject) parameters.get(PARAMETER_CATEGORY))
+ .getObjectId())
+ .orElseThrow(() -> new IllegalArgumentException(String.format(
+ "No category with ID %d in the database.",
+ ((CcmObject) parameters.get(PARAMETER_CATEGORY)).getObjectId())));
+
+ final Optional indexObj = categoryManager
+ .getIndexObject(category);
+
+ if (indexObj.isPresent()) {
+
+ if (indexObj.get() instanceof ContentItem) {
+
+ final ContentItem indexItem;
+ if (itemManager.isLive((ContentItem) indexObj.get())) {
+ indexItem = itemManager
+ .getLiveVersion((ContentItem) indexObj.get(),
+ ContentItem.class)
+ .get();
+ } else {
+ throw new NotFoundException(String
+ .format(
+ "The index item %s of category %s does not have "
+ + "a live version.",
+ Objects.toString(indexObj),
+ Objects.toString(category)));
+ }
+
+ if (permissionChecker.isPermitted(ItemPrivileges.VIEW_PUBLISHED,
+ indexItem)) {
+ return generateGreetingItem(componentModel,
+ parameters,
+ indexItem);
+ } else {
+ throw new WebApplicationException(
+ "You are not permitted to view the view version of this item.",
+ Response.Status.UNAUTHORIZED);
+ }
+ } else {
+ throw new NotFoundException(String
+ .format("The index object %s of category %s is not a "
+ + "ContentItem.",
+ Objects.toString(indexObj),
+ Objects.toString(category)));
+ }
+ } else {
+ throw new NotFoundException(String
+ .format("The category %s does not have a index item.",
+ Objects.toString(category)));
+ }
+ }
+
+ private Map generateGreetingItem(
+ final GreetingItem componentModel,
+ final Map parameters,
+ final ContentItem item) {
+
+ final String language = (String) parameters.get(PARAMETER_LANGUAGE);
+
+ if (iteml10nManager.hasLanguage(item, new Locale(language))) {
+
+ final BeanInfo beanInfo;
+ try {
+ beanInfo = Introspector.getBeanInfo(item.getClass());
+ } catch (IntrospectionException ex) {
+ throw new UnexpectedErrorException(ex);
+ }
+
+ final PropertyDescriptor[] properties = beanInfo
+ .getPropertyDescriptors();
+
+ final Map result = new HashMap<>();
+
+ for (final PropertyDescriptor propertyDescriptor : properties) {
+ renderProperty(propertyDescriptor, componentModel, item, result);
+ }
+
+ return result;
+ } else {
+ throw new NotFoundException("Requested language is not available.");
+ }
+ }
+
+ private void renderProperty(final PropertyDescriptor propertyDescriptor,
+ final GreetingItem componentModel,
+ final ContentItem item,
+ final Map result) {
+
+ final String propertyName = propertyDescriptor.getName();
+ if (componentModel.getExcludedPropertyPaths().contains(propertyName)) {
+ return;
+ }
+
+ final Method readMethod = propertyDescriptor.getReadMethod();
+ if (Collection.class.isAssignableFrom(propertyDescriptor
+ .getPropertyType())) {
+
+ final Map associated;
+ try {
+ associated = generateAssociatedObject(readMethod.invoke(item));
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new UnsupportedOperationException(ex);
+ }
+ result.put(propertyName, associated);
+ } else if (isValueType(propertyDescriptor.getPropertyType())) {
+ try {
+ result.put(propertyName, readMethod.invoke(item));
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ throw new UnexpectedErrorException(ex);
+ }
+ } else {
+ //ToDo
+ }
+
+ }
+
+ private Map generateAssociatedObject(final Object obj) {
+
+ final BeanInfo beanInfo;
+ try {
+ beanInfo = Introspector.getBeanInfo(obj.getClass());
+ } catch (IntrospectionException ex) {
+ throw new UnexpectedErrorException(ex);
+ }
+
+ final PropertyDescriptor[] properties = beanInfo
+ .getPropertyDescriptors();
+
+ final Map result = new HashMap<>();
+ for (final PropertyDescriptor propertyDescriptor : properties) {
+ final Class> type = propertyDescriptor.getPropertyType();
+ if (isValueType(type)) {
+ final Method readMethod = propertyDescriptor.getReadMethod();
+ try {
+ result.put(propertyDescriptor.getName(),
+ readMethod.invoke(obj));
+ } catch (IllegalAccessException
+ | InvocationTargetException ex) {
+ throw new UnexpectedErrorException(ex);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private boolean isValueType(final Class> typeToTest) {
+ final Class>[] types = new Class>[]{
+ Boolean.class,
+ Boolean.TYPE,
+ Character.class,
+ Character.TYPE,
+ Byte.class,
+ Byte.TYPE,
+ Double.class,
+ Double.TYPE,
+ Float.class,
+ Float.TYPE,
+ Integer.class,
+ Integer.TYPE,
+ Long.class,
+ Long.TYPE,
+ Short.class,
+ Short.TYPE,
+ String.class
+ };
+
+ for (final Class> type : types) {
+ if (type.isAssignableFrom(typeToTest)) {
+ return true;
+ }
+ }
+
+ return typeToTest.isArray()
+ && (typeToTest.getComponentType()
+ .isAssignableFrom(Byte.class)
+ || typeToTest.getComponentType()
+ .isAssignableFrom(Byte.TYPE));
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/pages/Page.java b/ccm-cms/src/main/java/org/librecms/pages/Page.java
index d0b2d714d..a36f95e37 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/Page.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/Page.java
@@ -18,7 +18,7 @@
*/
package org.librecms.pages;
-import org.libreccm.categorization.Category;
+import org.libreccm.core.CcmObject;
import org.libreccm.pagemodel.PageModel;
import java.io.Serializable;
@@ -26,22 +26,23 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
-import javax.persistence.Column;
+import javax.persistence.CollectionTable;
+import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.MapKeyJoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
import javax.persistence.Table;
import static org.librecms.CmsConstants.*;
+import static org.librecms.pages.PagesConstants.*;
/**
*
@@ -52,22 +53,17 @@ import static org.librecms.CmsConstants.*;
@NamedQueries(
@NamedQuery(
name = "Page.findForCategory",
- query = "SELECT p FROM Page p WHERE p.category = :category"
+ query = "SELECT p "
+ + "FROM Page p "
+ + "JOIN p.categories c "
+ + "WHERE c.category = :category "
+ + "AND C.type = '" + CATEGORIZATION_TYPE_PAGE_CONF + "'"
)
)
-public class Page implements Serializable {
+public class Page extends CcmObject implements Serializable {
private static final long serialVersionUID = 5108486858438122008L;
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- @Column(name = "PAGE_ID")
- private long pageId;
-
- @OneToOne
- @JoinColumn(name = "CATEGORY_ID")
- private Category category;
-
@ManyToOne
@JoinColumn(name = "INDEX_PAGE_MODEL_ID")
private PageModel indexPageModel;
@@ -76,30 +72,20 @@ public class Page implements Serializable {
@JoinColumn(name = "ITEM_PAGE_MODEL_ID")
private PageModel itemPageModel;
- @Embedded
- @JoinTable(name = "PAGE_THEME_CONFIGURATIONS",
- schema = DB_SCHEMA,
- joinColumns = {
- @JoinColumn(name = "PAGE_ID")
- })
+ @ElementCollection
+// @JoinTable(name = "PAGE_THEME_CONFIGURATIONS",
+// schema = DB_SCHEMA,
+// joinColumns = {
+// @JoinColumn(name = "PAGE_ID")
+// })
+ @CollectionTable(name = "PAGE_THEME_CONFIGURATIONS",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "PAGE_ID")
+ })
+ @MapKeyColumn(name = "THEME")
private Map themeConfiguration;
- public long getPageId() {
- return pageId;
- }
-
- protected void setPageId(final long pageId) {
- this.pageId = pageId;
- }
-
- public Category getCategory() {
- return category;
- }
-
- public void setCategory(final Category category) {
- this.category = category;
- }
-
public PageModel getIndexPageModel() {
return indexPageModel;
}
@@ -126,4 +112,53 @@ public class Page implements Serializable {
this.themeConfiguration = new HashMap<>(themeConfiguration);
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 47 * hash + Objects.hashCode(indexPageModel);
+ hash = 47 * hash + Objects.hashCode(itemPageModel);
+ hash = 47 * hash + Objects.hashCode(themeConfiguration);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Page)) {
+ return false;
+ }
+ final Page other = (Page) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (!Objects.equals(indexPageModel, other.getIndexPageModel())) {
+ return false;
+ }
+ if (!Objects.equals(itemPageModel, other.getItemPageModel())) {
+ return false;
+ }
+ return Objects.equals(themeConfiguration, other.getThemeConfiguration());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+ return obj instanceof Page;
+ }
+
+ @Override
+ public String toString(final String data) {
+ return super.toString(String.format(", indexPageModel = %s, "
+ + "itemPageModel = %s, "
+ + "themeConfiguration = %s%s",
+ Objects.toString(indexPageModel),
+ Objects.toString(itemPageModel),
+ Objects.toString(themeConfiguration),
+ data));
+ }
+
}
diff --git a/ccm-cms/src/main/java/org/librecms/pages/PageManager.java b/ccm-cms/src/main/java/org/librecms/pages/PageManager.java
index 4c6ac65d9..601dfcbb4 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/PageManager.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/PageManager.java
@@ -19,6 +19,7 @@
package org.librecms.pages;
import org.libreccm.categorization.Category;
+import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import java.util.Optional;
@@ -34,9 +35,12 @@ import javax.transaction.Transactional;
@RequestScoped
public class PageManager {
+ @Inject
+ private CategoryManager categoryManager;
+
@Inject
private CategoryRepository categoryRepo;
-
+
@Inject
private PageRepository pageRepo;
@@ -66,9 +70,8 @@ public class PageManager {
public Page createPageForCategory(final Category category) {
final Page page = new Page();
- page.setCategory(category);
-
pageRepo.save(page);
+ categoryManager.addObjectToCategory(page, category);
return page;
}
diff --git a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java
index 5d02d5db7..5a205bc67 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/PageRepository.java
@@ -69,7 +69,7 @@ public class PageRepository extends AbstractEntityRepository{
@Override
public boolean isNew(final Page page) {
- return page.getPageId() == 0;
+ return page.getObjectId() == 0;
}
diff --git a/ccm-cms/src/main/java/org/librecms/pages/Pages.java b/ccm-cms/src/main/java/org/librecms/pages/Pages.java
index ed7daf702..9be461c18 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/Pages.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/Pages.java
@@ -39,7 +39,7 @@ import static org.librecms.CmsConstants.*;
* @author Jens Pelzetter
*/
@Entity
-@Table(name = "PAGES", schema = DB_SCHEMA)
+@Table(name = "PAGES_APP", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(
name = "Pages.findForSite",
diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesConstants.java b/ccm-cms/src/main/java/org/librecms/pages/PagesConstants.java
new file mode 100644
index 000000000..cb519da38
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/pages/PagesConstants.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 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.pages;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public final class PagesConstants {
+
+ private PagesConstants() {
+ //Nothing
+ }
+
+ public static final String CATEGORIZATION_TYPE_PAGE_CONF = "PAGE_CONFIGURATION";
+
+ public static final String PARAMETER_CATEGORY = "category";
+ public static final String PARAMETER_ITEMNAME = "itemName";
+ public static final String PARAMETER_LANGUAGE = "language";
+
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java b/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java
index b9b212127..7b530627b 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/PagesRepository.java
@@ -18,14 +18,11 @@
*/
package org.librecms.pages;
-import org.libreccm.categorization.Category;
import org.libreccm.core.AbstractEntityRepository;
import org.libreccm.core.CoreConstants;
-import org.libreccm.pagemodel.PageModelVersion;
import org.libreccm.security.RequiresPrivilege;
import org.libreccm.sites.SiteRepository;
-import org.libreccm.pagemodel.PageModel;
import java.util.Optional;
diff --git a/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java b/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java
index 8ed6d2c43..fe62a7f88 100644
--- a/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java
+++ b/ccm-cms/src/main/java/org/librecms/pages/PagesRouter.java
@@ -18,9 +18,12 @@
*/
package org.librecms.pages;
+import com.arsdigita.kernel.KernelConfig;
+
import org.libreccm.categorization.Category;
-import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
+import org.libreccm.configuration.ConfigurationManager;
+import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelManager;
import org.libreccm.sites.Site;
@@ -29,12 +32,15 @@ import org.libreccm.theming.ThemeInfo;
import org.libreccm.theming.ThemeVersion;
import org.libreccm.theming.Themes;
+import java.net.URI;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
+import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
-import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.NotFoundException;
@@ -47,6 +53,8 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+import static org.librecms.pages.PagesConstants.*;
+
/**
*
* @author Jens Pelzetter
@@ -56,35 +64,98 @@ import javax.ws.rs.core.UriInfo;
public class PagesRouter {
@Inject
- private CategoryManager categoryManager;
+ private CategoryRepository categoryRepo;
@Inject
- private CategoryRepository categoryRepo;
+ private ConfigurationManager confManager;
+
+ @Inject
+ private GlobalizationHelper globalizationHelper;
@Inject
private CmsPageBuilder pageBuilder;
- @Inject
- private EntityManager entityManager;
-
@Inject
private PagesRepository pagesRepo;
- @Inject
- private PageModelManager pageModelManager;
-
- @Inject
- private PageRepository pageRepo;
-
@Inject
private PageManager pageManager;
+ @Inject
+ private PageModelManager pageModelManager;
+
@Inject
private SiteRepository siteRepo;
@Inject
private Themes themes;
+ private Locale defaultLocale;
+
+ @PostConstruct
+ private void init() {
+ final KernelConfig kernelConfig = confManager
+ .findConfiguration(KernelConfig.class);
+ defaultLocale = kernelConfig.getDefaultLocale();
+ }
+
+ @Path("/")
+ public Response getCategoryIndexPage(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page) {
+
+ final String domain = uriInfo.getBaseUri().getHost();
+ final Pages pages = getPages(domain);
+ final Category category = getCategory(domain, pages, page);
+
+ final Locale negoiatedLocale = globalizationHelper
+ .getNegotiatedLocale();
+
+ final String language;
+ if (category.getTitle().hasValue(negoiatedLocale)) {
+ language = negoiatedLocale.toString();
+ } else if (category.getTitle().hasValue(defaultLocale)) {
+ language = defaultLocale.toString();
+ } else {
+ throw new NotFoundException();
+ }
+
+ final String indexPage = String.format("/index.%s.html", language);
+ final URI uri = uriInfo.getBaseUriBuilder().path(indexPage).build();
+ return Response.temporaryRedirect(uri).build();
+ }
+
+ @Path("/index.html")
+ public Response getCategoryIndexPageAsHtml(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page) {
+
+ final String domain = uriInfo.getBaseUri().getHost();
+ final Pages pages = getPages(domain);
+ final Category category = getCategory(domain, pages, page);
+
+ final Locale negoiatedLocale = globalizationHelper
+ .getNegotiatedLocale();
+ final String language;
+ if (category.getTitle().hasValue(negoiatedLocale)) {
+ language = negoiatedLocale.toString();
+ } else if (category.getTitle().hasValue(defaultLocale)) {
+ language = defaultLocale.toString();
+ } else {
+ throw new NotFoundException();
+ }
+
+ final String indexPage = String.format("/index.%s.html", language);
+ final String path = uriInfo.getPath().replace("index.html", indexPage);
+
+ final URI uri = uriInfo.getBaseUriBuilder().replacePath(path).build();
+ return Response.temporaryRedirect(uri).build();
+ }
+
@Path("/index.{lang}.html")
@Produces("text/html")
@Transactional(Transactional.TxType.REQUIRED)
@@ -105,6 +176,180 @@ public class PagesRouter {
@DefaultValue("LIVE")
final String pageModelVersion) {
+ final Map buildResult = getCategoryIndexPage(
+ uriInfo, page, language, pageModelVersion);
+ final Site site = getSite(uriInfo);
+ final ThemeInfo themeInfo = getTheme(site, theme, themeVersion);
+
+ return themes.process(buildResult, themeInfo);
+ }
+
+ @Path("/index.{lang}.json")
+ @Produces("text/html")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Map getCategoryIndexPageAsJson(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page,
+ @PathParam("lang")
+ final String language,
+ @QueryParam("pagemodel-version")
+ @DefaultValue("LIVE")
+ final String pageModelVersion) {
+
+ return getCategoryIndexPage(uriInfo, page, language, pageModelVersion);
+ }
+
+ @Path("/index.{lang}.xml")
+ @Produces("text/html")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Map getCategoryIndexPageAsXml(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page,
+ @PathParam("lang")
+ final String language,
+ @QueryParam("pagemodel-version")
+ @DefaultValue("LIVE")
+ final String pageModelVersion) {
+
+ return getCategoryIndexPage(uriInfo, page, language, pageModelVersion);
+ }
+
+ @Path("/{name}")
+ public Response getItemPage(
+ @Context final UriInfo uriInfo,
+ @PathParam("page") final String page,
+ @PathParam("name") final String itemName) {
+
+ final String domain = uriInfo.getBaseUri().getHost();
+ final Pages pages = getPages(domain);
+ final Category category = getCategory(domain, pages, page);
+
+ final Locale negoiatedLocale = globalizationHelper
+ .getNegotiatedLocale();
+
+ final String language;
+ if (category.getTitle().hasValue(negoiatedLocale)) {
+ language = negoiatedLocale.toString();
+ } else if (category.getTitle().hasValue(defaultLocale)) {
+ language = defaultLocale.toString();
+ } else {
+ throw new NotFoundException();
+ }
+
+ final String itemPage = String.format("/%s.%s.html", itemName, language);
+ final URI uri = uriInfo.getBaseUriBuilder().path(itemPage).build();
+ return Response.temporaryRedirect(uri).build();
+ }
+
+ @Path("/{name},html")
+ public Response getItemPageAsHtml(
+ @Context final UriInfo uriInfo,
+ @PathParam("page") final String page,
+ @PathParam("name") final String itemName) {
+
+ final String domain = uriInfo.getBaseUri().getHost();
+ final Pages pages = getPages(domain);
+ final Category category = getCategory(domain, pages, page);
+
+ final Locale negoiatedLocale = globalizationHelper
+ .getNegotiatedLocale();
+
+ final String language;
+ if (category.getTitle().hasValue(negoiatedLocale)) {
+ language = negoiatedLocale.toString();
+ } else if (category.getTitle().hasValue(defaultLocale)) {
+ language = defaultLocale.toString();
+ } else {
+ throw new NotFoundException();
+ }
+
+ final String itemPage = String.format("/%s.%s.html", itemName, language);
+ final String path = uriInfo
+ .getPath()
+ .replace(String.format("%s.html", itemName), itemPage);
+
+ final URI uri = uriInfo.getBaseUriBuilder().replacePath(path).build();
+ return Response.temporaryRedirect(uri).build();
+ }
+
+ @Path("/{name}.{lang}.html")
+ public String getItemPageAsHtml(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page,
+ @PathParam("name")
+ final String itemName,
+ @PathParam("lang")
+ final String language,
+ @QueryParam("theme")
+ @DefaultValue("--DEFAULT--")
+ final String theme,
+ @QueryParam("theme-version")
+ @DefaultValue("LIVE")
+ final String themeVersion,
+ @QueryParam("pagemodel-version")
+ @DefaultValue("LIVE")
+ final String pageModelVersion) {
+
+ final Map buildResult = getCategoryItemPage(
+ uriInfo, page, itemName, language, pageModelVersion);
+ final Site site = getSite(uriInfo);
+ final ThemeInfo themeInfo = getTheme(site, page, themeVersion);
+
+ return themes.process(buildResult, themeInfo);
+ }
+
+ @Path("/{name}.{lang}.html")
+ public Map getItemPageAsJson(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page,
+ @PathParam("name")
+ final String itemName,
+ @PathParam("lang")
+ final String language,
+ @QueryParam("pagemodel-version")
+ @DefaultValue("LIVE")
+ final String pageModelVersion) {
+
+ return getCategoryItemPage(uriInfo,
+ page,
+ itemName,
+ language,
+ pageModelVersion);
+ }
+
+ @Path("/{name}.{lang}.html")
+ public Map getItemPageAsXml(
+ @Context
+ final UriInfo uriInfo,
+ @PathParam("page")
+ final String page,
+ @PathParam("name")
+ final String itemName,
+ @PathParam("lang")
+ final String language,
+ @QueryParam("pagemodel-version")
+ @DefaultValue("LIVE")
+ final String pageModelVersion) {
+
+ return getCategoryItemPage(uriInfo,
+ page,
+ itemName,
+ language,
+ pageModelVersion);
+ }
+
+ private Site getSite(final UriInfo uriInfo) {
+
+ Objects.requireNonNull(uriInfo);
+
final String domain = uriInfo.getBaseUri().getHost();
final Site site;
@@ -117,36 +362,37 @@ public class PagesRouter {
"No matching Site and no default Site."));
}
- final Pages pages = pagesRepo
+ return site;
+ }
+
+ private Pages getPages(final String domain) {
+
+ return pagesRepo
.findPagesForSite(domain)
.orElseThrow(() -> new NotFoundException(String
.format("No Pages for domain \"%s\" available.",
domain)));
+ }
- final Category category = categoryRepo
- .findByPath(pages.getCategoryDomain(), page)
+ private Category getCategory(final String domain,
+ final Pages pages,
+ final String pagePath) {
+
+ return categoryRepo
+ .findByPath(pages.getCategoryDomain(), pagePath)
.orElseThrow(() -> new NotFoundException(String.format(
- "No page for path \"%s\" in site \"%s\"",
- page,
+ "No Page for path \"%s\" in site \"%s\"",
+ pagePath,
domain)));
- final Page pageConf = pageManager.findPageForCategory(category);
+ }
- final PageModel pageModel = pageConf.getIndexPageModel();
+ private ThemeInfo getTheme(final Site site,
+ final String theme,
+ final String themeVersion) {
- final Map parameters = new HashMap<>();
- parameters.put("currentCategory", category);
-
- final Map buildResult;
- if (pageModel == null) {
- buildResult = pageBuilder.buildPage(parameters);
- } else {
- buildResult = pageBuilder.buildPage(pageModel, parameters);
- }
-
- final ThemeInfo themeInfo;
if ("--DEFAULT--".equals(theme)) {
- themeInfo = themes
+ return themes
.getTheme(site.getDefaultTheme(),
ThemeVersion.valueOf(themeVersion))
.orElseThrow(() -> new WebApplicationException(
@@ -156,71 +402,110 @@ public class PagesRouter {
site.getDefaultTheme()),
Response.Status.INTERNAL_SERVER_ERROR));
} else {
- themeInfo = themes.getTheme(theme,
- ThemeVersion.valueOf(themeVersion))
+ return themes.getTheme(theme,
+ ThemeVersion.valueOf(themeVersion))
.orElseThrow(() -> new WebApplicationException(
String.format("The theme \"%s\" is not available.",
theme),
Response.Status.BAD_REQUEST));
}
-
- return themes.process(buildResult, themeInfo);
}
- @Path("/index.{lang}.json")
- @Produces("text/html")
- @Transactional(Transactional.TxType.REQUIRED)
- public String getCategoryIndexPageAsJson(
- @Context
+ private Page getPage(final UriInfo uriInfo,
+ final String pagePath,
+ final String language,
+ final Map parameters) {
+
+ Objects.requireNonNull(uriInfo);
+ Objects.requireNonNull(pagePath);
+ Objects.requireNonNull(parameters);
+
+ final String domain = uriInfo.getBaseUri().getHost();
+ final Pages pages = getPages(domain);
+ final Category category = getCategory(domain, pages, pagePath);
+
+ final Locale locale = new Locale(language);
+ if (!category.getTitle().hasValue(locale)) {
+ throw new NotFoundException();
+ }
+
+ globalizationHelper.setSelectedLocale(locale);
+
+ parameters.put(PARAMETER_CATEGORY, category);
+ return pageManager.findPageForCategory(category);
+ }
+
+ private Map buildPage(
+ final PageModel pageModel,
+ final Map parameters) {
+
+ Objects.requireNonNull(pageModel);
+ Objects.requireNonNull(parameters);
+
+ final Map result;
+ if (pageModel == null) {
+ result = pageBuilder.buildPage(parameters);
+ } else {
+ result = pageBuilder.buildPage(pageModel, parameters);
+ }
+
+ return result;
+ }
+
+ private Map getCategoryIndexPage(
final UriInfo uriInfo,
- @PathParam("page")
- final String page,
- @PathParam("lang")
+ final String pagePath,
final String language,
- @QueryParam("theme")
- @DefaultValue("--DEFAULT--")
- final String theme,
- @QueryParam("theme-version")
- @DefaultValue("LIVE")
- final String themeVersion,
- @QueryParam("pagemodel-version")
- @DefaultValue("LIVE")
final String pageModelVersion) {
- throw new UnsupportedOperationException();
+ final Map parameters = new HashMap<>();
+ final Page page = getPage(uriInfo, pagePath, language, parameters);
+
+ final PageModel pageModel;
+ if ("DRAFT".equals(pageModelVersion)) {
+ pageModel = pageModelManager.getDraftVersion(page
+ .getIndexPageModel());
+ } else {
+ pageModel = pageModelManager
+ .getLiveVersion(page.getIndexPageModel())
+ .orElseThrow(() -> new NotFoundException(String
+ .format("The PageModel for the index page of the category"
+ + "\"%s\" is not available as live version.",
+ pagePath)));
+ }
+
+ parameters.put(PARAMETER_LANGUAGE, language);
+
+ return buildPage(pageModel, parameters);
}
-
- @Path("/index.{lang}.xml")
- @Produces("text/html")
- @Transactional(Transactional.TxType.REQUIRED)
- public String getCategoryIndexPageAsXml(
- @Context
+
+ private Map getCategoryItemPage(
final UriInfo uriInfo,
- @PathParam("page")
- final String page,
- @PathParam("lang")
+ final String pagePath,
+ final String itemName,
final String language,
- @QueryParam("theme")
- @DefaultValue("--DEFAULT--")
- final String theme,
- @QueryParam("theme-version")
- @DefaultValue("LIVE")
- final String themeVersion,
- @QueryParam("pagemodel-version")
- @DefaultValue("LIVE")
final String pageModelVersion) {
- throw new UnsupportedOperationException();
- }
+ final Map parameters = new HashMap<>();
+ final Page page = getPage(uriInfo, pagePath, language, parameters);
- @Path("/{name}.{lang}.html")
- public String getPage(
- @Context final UriInfo uriInfo,
- @PathParam("page") final String page,
- @PathParam("lang") final String language,
- @QueryParam("theme") @DefaultValue("--DEFAULT--") final String theme) {
+ final PageModel pageModel;
+ if ("DRAFT".equals(pageModelVersion)) {
+ pageModel = pageModelManager.getDraftVersion(page
+ .getItemPageModel());
+ } else {
+ pageModel = pageModelManager
+ .getLiveVersion(page.getItemPageModel())
+ .orElseThrow(() -> new NotFoundException(String
+ .format("The PageModel for the index page of the category"
+ + "\"%s\" is not available as live version.",
+ pagePath)));
+ }
- throw new UnsupportedOperationException();
+ parameters.put(PARAMETER_ITEMNAME, itemName);
+ parameters.put(PARAMETER_LANGUAGE, language);
+
+ return buildPage(pageModel, parameters);
}
}
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_pages.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_pages.sql
new file mode 100644
index 000000000..03ad269e7
--- /dev/null
+++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_pages.sql
@@ -0,0 +1,56 @@
+ create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
+ PAGE_ID bigint not null,
+ INDEX_PAGE_TEMPLATE varchar(255),
+ ITEM_PAGE_TEMPLATE varchar(255),
+ THEME varchar(255) not null,
+ primary key (PAGE_ID, THEME)
+);
+
+create table CCM_CMS.PAGES (
+ OBJECT_ID bigint not null,
+ INDEX_PAGE_MODEL_ID bigint,
+ ITEM_PAGE_MODEL_ID bigint,
+ primary key (OBJECT_ID)
+);
+
+create table CCM_CMS.PAGES_APP (
+ OBJECT_ID bigint not null,
+ CATEGORY_DOMAIN_ID bigint,
+ SITE_ID bigint,
+ primary key (OBJECT_ID)
+);
+
+alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
+ add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
+ foreign key (PAGE_ID)
+ references CCM_CMS.PAGES;
+
+alter table CCM_CMS.PAGES
+ add constraint FKqweb08d151ot4ij9io72w3yhx
+ foreign key (INDEX_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+alter table CCM_CMS.PAGES
+ add constraint FKg2p2ahbayc2coei72pk1lnenf
+ foreign key (ITEM_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+alter table CCM_CMS.PAGES
+ add constraint FKmgmth087tmxwieujn2vs5opbo
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FK5swx0e8pj0mm5t1es0lj4nwlx
+ foreign key (CATEGORY_DOMAIN_ID)
+ references CCM_CORE.CATEGORY_DOMAINS;
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FK3wkyn4oxa65f7svtj917m61jc
+ foreign key (SITE_ID)
+ references CCM_CORE.SITES;
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FKrrk4g7my3e4qkdoeiygkqxduy
+ foreign key (OBJECT_ID)
+ references CCM_CORE.APPLICATIONS;
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_sites.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_sites.sql
deleted file mode 100644
index ff1974007..000000000
--- a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/h2/V7_0_0_16__create_sites.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-create table CCM_CMS.SITES (
- DEFAULT_SITE boolean,
- NAME varchar(255),
- OBJECT_ID bigint not null,
- CATEGORY_DOMAIN_ID bigint,
- primary key (OBJECT_ID)
-);
-
-alter table CCM_CMS.SITES
- add constraint UK_fgjx0nuuxlgnuit724a96vw81 unique (NAME);
-
-alter table CCM_CMS.SITES
- add constraint FKmiysfmv1nkcso6bm18sjhvtm8
- foreign key (CATEGORY_DOMAIN_ID)
- references CCM_CORE.CATEGORY_DOMAINS;
-
-alter table CCM_CMS.SITES
- add constraint FK5kmn26x72uue9t3dfnjwes45
- foreign key (OBJECT_ID)
- references CCM_CORE.APPLICATIONS;
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_pages.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_pages.sql
new file mode 100644
index 000000000..545a5027c
--- /dev/null
+++ b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_pages.sql
@@ -0,0 +1,57 @@
+create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
+ PAGE_ID int8 not null,
+ INDEX_PAGE_TEMPLATE varchar(255),
+ ITEM_PAGE_TEMPLATE varchar(255),
+ THEME varchar(255) not null,
+ primary key (PAGE_ID, THEME)
+);
+
+create table CCM_CMS.PAGES (
+ OBJECT_ID int8 not null,
+ INDEX_PAGE_MODEL_ID int8,
+ ITEM_PAGE_MODEL_ID int8,
+ primary key (OBJECT_ID)
+);
+
+create table CCM_CMS.PAGES_APP (
+ OBJECT_ID int8 not null,
+ CATEGORY_DOMAIN_ID int8,
+ SITE_ID int8,
+ primary key (OBJECT_ID)
+);
+
+alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
+ add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
+ foreign key (PAGE_ID)
+ references CCM_CMS.PAGES;
+
+alter table CCM_CMS.PAGES
+ add constraint FKqweb08d151ot4ij9io72w3yhx
+ foreign key (INDEX_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+alter table CCM_CMS.PAGES
+ add constraint FKg2p2ahbayc2coei72pk1lnenf
+ foreign key (ITEM_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+alter table CCM_CMS.PAGES
+ add constraint FKmgmth087tmxwieujn2vs5opbo
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+);
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FK5swx0e8pj0mm5t1es0lj4nwlx
+ foreign key (CATEGORY_DOMAIN_ID)
+ references CCM_CORE.CATEGORY_DOMAINS;
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FK3wkyn4oxa65f7svtj917m61jc
+ foreign key (SITE_ID)
+ references CCM_CORE.SITES;
+
+alter table CCM_CMS.PAGES_APP
+ add constraint FKrrk4g7my3e4qkdoeiygkqxduy
+ foreign key (OBJECT_ID)
+ references CCM_CORE.APPLICATIONS;
\ No newline at end of file
diff --git a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_sites.sql b/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_sites.sql
deleted file mode 100644
index 7526e4211..000000000
--- a/ccm-cms/src/main/resources/db/migrations/org/librecms/ccm_cms/pgsql/V7_0_0_16__create_sites.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-create table CCM_CMS.SITES (
- DEFAULT_SITE boolean,
- NAME varchar(255),
- OBJECT_ID int8 not null,
- CATEGORY_DOMAIN_ID int8,
- primary key (OBJECT_ID)
-);
-
-alter table CCM_CMS.SITES
- add constraint UK_fgjx0nuuxlgnuit724a96vw81 unique (NAME);
-
-alter table CCM_CMS.SITES
- add constraint FKmiysfmv1nkcso6bm18sjhvtm8
- foreign key (CATEGORY_DOMAIN_ID)
- references CCM_CORE.CATEGORY_DOMAINS;
-
-alter table CCM_CMS.SITES
- add constraint FK5kmn26x72uue9t3dfnjwes45
- foreign key (OBJECT_ID)
- references CCM_CORE.APPLICATIONS;
diff --git a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql
index 88ef238e7..d7d361e8b 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql
@@ -3,7 +3,9 @@ drop schema if exists CCM_CORE;
drop sequence if exists HIBERNATE_SEQUENCE;
+
create schema CCM_CMS;
+
create schema CCM_CORE;
create table CCM_CMS.ARTICLE_TEXTS (
@@ -771,6 +773,28 @@ drop sequence if exists HIBERNATE_SEQUENCE;
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
+ create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
+ PAGE_ID bigint not null,
+ INDEX_PAGE_TEMPLATE varchar(255),
+ ITEM_PAGE_TEMPLATE varchar(255),
+ THEME varchar(255) not null,
+ primary key (PAGE_ID, THEME)
+ );
+
+ create table CCM_CMS.PAGES (
+ OBJECT_ID bigint not null,
+ INDEX_PAGE_MODEL_ID bigint,
+ ITEM_PAGE_MODEL_ID bigint,
+ primary key (OBJECT_ID)
+ );
+
+ create table CCM_CMS.PAGES_APP (
+ OBJECT_ID bigint not null,
+ CATEGORY_DOMAIN_ID bigint,
+ SITE_ID bigint,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.RELATED_LINKS (
OBJECT_ID bigint not null,
BOOKMARK_ID bigint,
@@ -814,14 +838,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
primary key (OBJECT_ID, REV)
);
- create table CCM_CMS.SITES (
- DEFAULT_SITE boolean,
- NAME varchar(255),
- OBJECT_ID bigint not null,
- CATEGORY_DOMAIN_ID bigint,
- primary key (OBJECT_ID)
- );
-
create table CCM_CMS.VIDEO_ASSETS (
HEIGHT bigint,
WIDTH bigint,
@@ -851,9 +867,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
alter table CCM_CMS.CONTENT_SECTION_WORKFLOW_TEMPLATES
add constraint UK_goj42ghwu4tf1akfb2r6ensns unique (WORKFLOW_TEMPLATE_ID);
- alter table CCM_CMS.SITES
- add constraint UK_fgjx0nuuxlgnuit724a96vw81 unique (NAME);
-
create table CCM_CORE.APPLICATIONS (
APPLICATION_TYPE varchar(1024) not null,
PRIMARY_URL varchar(1024) not null,
@@ -1379,11 +1392,11 @@ drop sequence if exists HIBERNATE_SEQUENCE;
SETTING_ID bigint not null,
CONFIGURATION_CLASS varchar(512) not null,
NAME varchar(512) not null,
- SETTING_VALUE_BOOLEAN boolean,
- SETTING_VALUE_STRING varchar(1024),
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
- SETTING_VALUE_LONG bigint,
+ SETTING_VALUE_STRING varchar(1024),
SETTING_VALUE_DOUBLE double,
+ SETTING_VALUE_LONG bigint,
+ SETTING_VALUE_BOOLEAN boolean,
primary key (SETTING_ID)
);
@@ -1404,6 +1417,14 @@ drop sequence if exists HIBERNATE_SEQUENCE;
value varchar(255)
);
+ create table CCM_CORE.SITES (
+ DEFAULT_SITE boolean,
+ DEFAULT_THEME varchar(255),
+ DOMAIN_OF_SITE varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CORE.THREADS (
OBJECT_ID bigint not null,
ROOT_ID bigint,
@@ -1529,6 +1550,9 @@ drop sequence if exists HIBERNATE_SEQUENCE;
alter table CCM_CORE.SETTINGS
add constraint UK5whinfxdaepqs09e5ia9y71uk unique (CONFIGURATION_CLASS, NAME);
+ alter table CCM_CORE.SITES
+ add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE);
+
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
add constraint UK_4nnedf08odyjxalfkg16fmjoi unique (UUID);
@@ -2220,6 +2244,41 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
+ alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
+ add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
+ foreign key (PAGE_ID)
+ references CCM_CMS.PAGES;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKqweb08d151ot4ij9io72w3yhx
+ foreign key (INDEX_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKg2p2ahbayc2coei72pk1lnenf
+ foreign key (ITEM_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKmgmth087tmxwieujn2vs5opbo
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FK5swx0e8pj0mm5t1es0lj4nwlx
+ foreign key (CATEGORY_DOMAIN_ID)
+ references CCM_CORE.CATEGORY_DOMAINS;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FK3wkyn4oxa65f7svtj917m61jc
+ foreign key (SITE_ID)
+ references CCM_CORE.SITES;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FKrrk4g7my3e4qkdoeiygkqxduy
+ foreign key (OBJECT_ID)
+ references CCM_CORE.APPLICATIONS;
+
alter table CCM_CMS.RELATED_LINKS
add constraint FKb517dnfj56oby2s34jp1omuim
foreign key (BOOKMARK_ID)
@@ -2265,16 +2324,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (OBJECT_ID, REV)
references CCM_CMS.ASSETS_AUD;
- alter table CCM_CMS.SITES
- add constraint FKmiysfmv1nkcso6bm18sjhvtm8
- foreign key (CATEGORY_DOMAIN_ID)
- references CCM_CORE.CATEGORY_DOMAINS;
-
- alter table CCM_CMS.SITES
- add constraint FK5kmn26x72uue9t3dfnjwes45
- foreign key (OBJECT_ID)
- references CCM_CORE.APPLICATIONS;
-
alter table CCM_CMS.VIDEO_ASSETS
add constraint FKjuywvv7wq9pyid5b6ivyrc0yk
foreign key (LEGAL_METADATA_ID)
@@ -2710,6 +2759,11 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (LIST_ID)
references CCM_CORE.SETTINGS;
+ alter table CCM_CORE.SITES
+ add constraint FKrca95c6p023men53b8ayu26kp
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
alter table CCM_CORE.THREADS
add constraint FKsx08mpwvwnw97uwdgjs76q39g
foreign key (ROOT_ID)
diff --git a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql
index 84913c2e5..b0f45ce57 100644
--- a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql
+++ b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql
@@ -4,6 +4,7 @@ drop schema if exists CCM_CORE cascade;
drop sequence if exists HIBERNATE_SEQUENCE;
create schema CCM_CMS;
+
create schema CCM_CORE;
create table CCM_CMS.ARTICLE_TEXTS (
@@ -771,6 +772,28 @@ drop sequence if exists HIBERNATE_SEQUENCE;
primary key (REV, OBJECT_ID, LOCALIZED_VALUE, LOCALE)
);
+ create table CCM_CMS.PAGE_THEME_CONFIGURATIONS (
+ PAGE_ID int8 not null,
+ INDEX_PAGE_TEMPLATE varchar(255),
+ ITEM_PAGE_TEMPLATE varchar(255),
+ THEME varchar(255) not null,
+ primary key (PAGE_ID, THEME)
+ );
+
+ create table CCM_CMS.PAGES (
+ OBJECT_ID int8 not null,
+ INDEX_PAGE_MODEL_ID int8,
+ ITEM_PAGE_MODEL_ID int8,
+ primary key (OBJECT_ID)
+ );
+
+ create table CCM_CMS.PAGES_APP (
+ OBJECT_ID int8 not null,
+ CATEGORY_DOMAIN_ID int8,
+ SITE_ID int8,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CMS.RELATED_LINKS (
OBJECT_ID int8 not null,
BOOKMARK_ID int8,
@@ -814,14 +837,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
primary key (OBJECT_ID, REV)
);
- create table CCM_CMS.SITES (
- DEFAULT_SITE boolean,
- NAME varchar(255),
- OBJECT_ID int8 not null,
- CATEGORY_DOMAIN_ID int8,
- primary key (OBJECT_ID)
- );
-
create table CCM_CMS.VIDEO_ASSETS (
HEIGHT int8,
WIDTH int8,
@@ -851,9 +866,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
alter table CCM_CMS.CONTENT_SECTION_WORKFLOW_TEMPLATES
add constraint UK_goj42ghwu4tf1akfb2r6ensns unique (WORKFLOW_TEMPLATE_ID);
- alter table CCM_CMS.SITES
- add constraint UK_fgjx0nuuxlgnuit724a96vw81 unique (NAME);
-
create table CCM_CORE.APPLICATIONS (
APPLICATION_TYPE varchar(1024) not null,
PRIMARY_URL varchar(1024) not null,
@@ -1379,11 +1391,11 @@ drop sequence if exists HIBERNATE_SEQUENCE;
SETTING_ID int8 not null,
CONFIGURATION_CLASS varchar(512) not null,
NAME varchar(512) not null,
- SETTING_VALUE_BOOLEAN boolean,
- SETTING_VALUE_STRING varchar(1024),
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
- SETTING_VALUE_LONG int8,
+ SETTING_VALUE_STRING varchar(1024),
SETTING_VALUE_DOUBLE float8,
+ SETTING_VALUE_LONG int8,
+ SETTING_VALUE_BOOLEAN boolean,
primary key (SETTING_ID)
);
@@ -1404,6 +1416,14 @@ drop sequence if exists HIBERNATE_SEQUENCE;
value varchar(255)
);
+ create table CCM_CORE.SITES (
+ DEFAULT_SITE boolean,
+ DEFAULT_THEME varchar(255),
+ DOMAIN_OF_SITE varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CORE.THREADS (
OBJECT_ID int8 not null,
ROOT_ID int8,
@@ -1529,6 +1549,9 @@ drop sequence if exists HIBERNATE_SEQUENCE;
alter table CCM_CORE.SETTINGS
add constraint UK5whinfxdaepqs09e5ia9y71uk unique (CONFIGURATION_CLASS, NAME);
+ alter table CCM_CORE.SITES
+ add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE);
+
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
add constraint UK_4nnedf08odyjxalfkg16fmjoi unique (UUID);
@@ -2220,6 +2243,41 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (REVEND)
references CCM_CORE.CCM_REVISIONS;
+ alter table CCM_CMS.PAGE_THEME_CONFIGURATIONS
+ add constraint FK6l6xp6ex6sh2uuxfmeekf6ckn
+ foreign key (PAGE_ID)
+ references CCM_CMS.PAGES;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKqweb08d151ot4ij9io72w3yhx
+ foreign key (INDEX_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKg2p2ahbayc2coei72pk1lnenf
+ foreign key (ITEM_PAGE_MODEL_ID)
+ references CCM_CORE.PAGE_MODELS;
+
+ alter table CCM_CMS.PAGES
+ add constraint FKmgmth087tmxwieujn2vs5opbo
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FK5swx0e8pj0mm5t1es0lj4nwlx
+ foreign key (CATEGORY_DOMAIN_ID)
+ references CCM_CORE.CATEGORY_DOMAINS;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FK3wkyn4oxa65f7svtj917m61jc
+ foreign key (SITE_ID)
+ references CCM_CORE.SITES;
+
+ alter table CCM_CMS.PAGES_APP
+ add constraint FKrrk4g7my3e4qkdoeiygkqxduy
+ foreign key (OBJECT_ID)
+ references CCM_CORE.APPLICATIONS;
+
alter table CCM_CMS.RELATED_LINKS
add constraint FKb517dnfj56oby2s34jp1omuim
foreign key (BOOKMARK_ID)
@@ -2265,16 +2323,6 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (OBJECT_ID, REV)
references CCM_CMS.ASSETS_AUD;
- alter table CCM_CMS.SITES
- add constraint FKmiysfmv1nkcso6bm18sjhvtm8
- foreign key (CATEGORY_DOMAIN_ID)
- references CCM_CORE.CATEGORY_DOMAINS;
-
- alter table CCM_CMS.SITES
- add constraint FK5kmn26x72uue9t3dfnjwes45
- foreign key (OBJECT_ID)
- references CCM_CORE.APPLICATIONS;
-
alter table CCM_CMS.VIDEO_ASSETS
add constraint FKjuywvv7wq9pyid5b6ivyrc0yk
foreign key (LEGAL_METADATA_ID)
@@ -2710,6 +2758,11 @@ drop sequence if exists HIBERNATE_SEQUENCE;
foreign key (LIST_ID)
references CCM_CORE.SETTINGS;
+ alter table CCM_CORE.SITES
+ add constraint FKrca95c6p023men53b8ayu26kp
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
alter table CCM_CORE.THREADS
add constraint FKsx08mpwvwnw97uwdgjs76q39g
foreign key (ROOT_ID)
diff --git a/ccm-core/src/main/java/org/libreccm/l10n/GlobalizationHelper.java b/ccm-core/src/main/java/org/libreccm/l10n/GlobalizationHelper.java
index 33ca9c515..dcc3d365d 100644
--- a/ccm-core/src/main/java/org/libreccm/l10n/GlobalizationHelper.java
+++ b/ccm-core/src/main/java/org/libreccm/l10n/GlobalizationHelper.java
@@ -178,6 +178,12 @@ public class GlobalizationHelper {
return selected;
}
+
+ public void setSelectedLocale(final Locale locale) {
+
+ final HttpSession session = request.getSession(true);
+ session.setAttribute(LANG_PARAM, locale.toString());
+ }
/**
* Retrieve the {@link ResourceBundle} identified by {@code name} for the
diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_16__create_sites.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_16__create_sites.sql
new file mode 100644
index 000000000..ff6abba4e
--- /dev/null
+++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_16__create_sites.sql
@@ -0,0 +1,16 @@
+create table CCM_CORE.SITES (
+ DEFAULT_SITE boolean,
+ DEFAULT_THEME varchar(255),
+ DOMAIN_OF_SITE varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+);
+
+alter table CCM_CORE.SITES
+ add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE);
+
+alter table CCM_CORE.SITES
+ add constraint FKrca95c6p023men53b8ayu26kp
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_16__create_sites.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_16__create_sites.sql
new file mode 100644
index 000000000..cb937955a
--- /dev/null
+++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_16__create_sites.sql
@@ -0,0 +1,16 @@
+create table CCM_CORE.SITES (
+ DEFAULT_SITE boolean,
+ DEFAULT_THEME varchar(255),
+ DOMAIN_OF_SITE varchar(255),
+ OBJECT_ID int8 not null,
+ primary key (OBJECT_ID)
+);
+
+alter table CCM_CORE.SITES
+ add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE);
+
+alter table CCM_CORE.SITES
+ add constraint FKrca95c6p023men53b8ayu26kp
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
diff --git a/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql b/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql
index 5a0d4b856..114218bc4 100644
--- a/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql
+++ b/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql
@@ -2,7 +2,8 @@ drop schema if exists CCM_CORE;
drop sequence if exists HIBERNATE_SEQUENCE;
-create schema CCM_CORE;
+
+ create schema CCM_CORE;
create table CCM_CORE.APPLICATIONS (
APPLICATION_TYPE varchar(1024) not null,
@@ -529,11 +530,11 @@ create schema CCM_CORE;
SETTING_ID bigint not null,
CONFIGURATION_CLASS varchar(512) not null,
NAME varchar(512) not null,
- SETTING_VALUE_BOOLEAN boolean,
- SETTING_VALUE_BIG_DECIMAL decimal(19,2),
SETTING_VALUE_LONG bigint,
+ SETTING_VALUE_BIG_DECIMAL decimal(19,2),
SETTING_VALUE_DOUBLE double,
SETTING_VALUE_STRING varchar(1024),
+ SETTING_VALUE_BOOLEAN boolean,
primary key (SETTING_ID)
);
@@ -554,6 +555,14 @@ create schema CCM_CORE;
value varchar(255)
);
+ create table CCM_CORE.SITES (
+ DEFAULT_SITE boolean,
+ DEFAULT_THEME varchar(255),
+ DOMAIN_OF_SITE varchar(255),
+ OBJECT_ID bigint not null,
+ primary key (OBJECT_ID)
+ );
+
create table CCM_CORE.THREADS (
OBJECT_ID bigint not null,
ROOT_ID bigint,
@@ -679,6 +688,9 @@ create schema CCM_CORE;
alter table CCM_CORE.SETTINGS
add constraint UK5whinfxdaepqs09e5ia9y71uk unique (CONFIGURATION_CLASS, NAME);
+ alter table CCM_CORE.SITES
+ add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE);
+
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
add constraint UK_4nnedf08odyjxalfkg16fmjoi unique (UUID);
@@ -1105,6 +1117,11 @@ create schema CCM_CORE;
foreign key (LIST_ID)
references CCM_CORE.SETTINGS;
+ alter table CCM_CORE.SITES
+ add constraint FKrca95c6p023men53b8ayu26kp
+ foreign key (OBJECT_ID)
+ references CCM_CORE.CCM_OBJECTS;
+
alter table CCM_CORE.THREADS
add constraint FKsx08mpwvwnw97uwdgjs76q39g
foreign key (ROOT_ID)
diff --git a/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql b/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql
index 67041e43b..cd634eb75 100644
--- a/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql
+++ b/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql
@@ -1203,4 +1203,3 @@ drop sequence if exists HIBERNATE_SEQUENCE;
alter table CCM_CORE.WORKFLOWS
add constraint FK9ray5beiny6wm2mi0uwyecay2
foreign key (TEMPLATE_ID)
- references CCM_CORE.WORKFLOWS;
\ No newline at end of file