* Ignore IDEA files
* Publishing PageModels from the PageModelEditor


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5535 8810af33-2d31-482b-a856-94f89814c4df
jensp 2018-06-17 15:44:07 +00:00
parent a7bdc427b9
commit 259a27079a
8 changed files with 330 additions and 177 deletions

View File

@ -62,7 +62,6 @@ import javax.xml.bind.annotation.XmlTransient;
* page. * page.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*
* @see PageModelRepository * @see PageModelRepository
* @see PageModelManager * @see PageModelManager
* @see PageRenderer * @see PageRenderer
@ -71,102 +70,116 @@ import javax.xml.bind.annotation.XmlTransient;
@Inheritance(strategy = InheritanceType.JOINED) @Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA) @Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA)
@NamedQueries({ @NamedQueries({
@NamedQuery( @NamedQuery(
name = "PageModel.findAllDraftModels", name = "PageModel.findAllDraftModels",
query = "SELECT p FROM PageModel p " query = "SELECT p FROM PageModel p "
+ "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT") + "WHERE p.version = org.libreccm.pagemodel"
, + ".PageModelVersion.DRAFT")
@NamedQuery( ,
name = "PageModel.findAllLiveModels", @NamedQuery(
query = "SELECT p FROM PageModel p " name = "PageModel.findAllLiveModels",
+ "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") query = "SELECT p FROM PageModel p "
, + "WHERE p.version = org.libreccm.pagemodel"
@NamedQuery( + ".PageModelVersion.LIVE")
name = "PageModel.findDraftVersion", ,
query = "SELECT p FROM PageModel p " @NamedQuery(
+ "WHERE p.modelUuid = :uuid " name = "PageModel.findDraftVersion",
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT") query = "SELECT p FROM PageModel p "
, + "WHERE p.modelUuid = :uuid "
@NamedQuery( + "AND p.version = org.libreccm.pagemodel"
name = "PageModel.hasLiveVersion", + ".PageModelVersion.DRAFT")
query = "SELECT (CASE WHEN COUNT(p) > 0 THEN true ELSE False END) " ,
+ "FROM PageModel p " @NamedQuery(
+ "WHERE p.modelUuid = :uuid " name = "PageModel.hasLiveVersion",
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" query =
) "SELECT (CASE WHEN COUNT(p) > 0 THEN true ELSE "
, + "False END) "
@NamedQuery( + "FROM PageModel p "
name = "PageModel.findLiveVersion", + "WHERE p.modelUuid = :uuid "
query = "SELECT p FROM PageModel p " + "AND p.version = org.libreccm.pagemodel"
+ "WHERE p.modelUuid = :uuid " + ".PageModelVersion.LIVE"
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") )
, ,
@NamedQuery( @NamedQuery(
name = "PageModel.findDraftByApplication", name = "PageModel.findLiveVersion",
query = "SELECT p FROM PageModel p " query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application " + "WHERE p.modelUuid = :uuid "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + "AND p.version = org.libreccm.pagemodel"
) + ".PageModelVersion.LIVE")
, ,
@NamedQuery( @NamedQuery(
name = "PageModel.findDraftByApplicationAndName", name = "PageModel.findDraftByApplication",
query = "SELECT p FROM PageModel p " query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application " + "WHERE p.application = :application "
+ "AND p.name = :name " + "AND p.version = org.libreccm.pagemodel"
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + ".PageModelVersion.DRAFT"
) )
, ,
@NamedQuery( @NamedQuery(
name = "PageModel.countDraftByApplicationAndName", name = "PageModel.findDraftByApplicationAndName",
query = "SELECT COUNT(p) FROM PageModel p " query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application " + "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" + "AND p.name = :name "
) + "AND p.version = org.libreccm.pagemodel"
, + ".PageModelVersion.DRAFT"
@NamedQuery( )
name = "PageModel.countDraftByApplication", ,
query = "SELECT COUNT(p) FROM PageModel p " @NamedQuery(
+ "WHERE p.application = :application " name = "PageModel.countDraftByApplicationAndName",
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT" query = "SELECT COUNT(p) FROM PageModel p "
) + "WHERE p.name = :name "
, + "AND p.application = :application "
@NamedQuery( + "AND p.version = org.libreccm.pagemodel"
name = "PageModel.findLiveByApplication", + ".PageModelVersion.DRAFT"
query = "SELECT p FROM PageModel p " )
+ "WHERE p.application = :application " ,
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") @NamedQuery(
, name = "PageModel.countDraftByApplication",
@NamedQuery( query = "SELECT COUNT(p) FROM PageModel p "
name = "PageModel.countLiveByApplication", + "WHERE p.application = :application "
query = "SELECT COUNT(p) FROM PageModel p " + "AND p.version = org.libreccm.pagemodel"
+ "WHERE p.application = :application " + ".PageModelVersion.DRAFT"
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE") )
, ,
@NamedQuery( @NamedQuery(
name = "PageModel.findLiveByApplicationAndName", name = "PageModel.findLiveByApplication",
query = "SELECT p FROM PageModel p " query = "SELECT p FROM PageModel p "
+ "WHERE p.name = :name " + "WHERE p.application = :application "
+ "AND p.application = :application " + "AND p.version = org.libreccm.pagemodel"
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" + ".PageModelVersion.LIVE")
) ,
, @NamedQuery(
@NamedQuery( name = "PageModel.countLiveByApplication",
name = "PageModel.countLiveByApplicationAndName", query = "SELECT COUNT(p) FROM PageModel p "
query = "SELECT COUNT(p) FROM PageModel p " + "WHERE p.application = :application "
+ "WHERE p.name = :name " + "AND p.version = org.libreccm.pagemodel"
+ "AND p.application = :application " + ".PageModelVersion.LIVE")
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE" ,
) @NamedQuery(
}) name = "PageModel.findLiveByApplicationAndName",
query = "SELECT p FROM PageModel p "
+ "WHERE p.name = :name "
+ "AND p.application = :application "
+ "AND p.version = org.libreccm.pagemodel"
+ ".PageModelVersion.LIVE"
)
,
@NamedQuery(
name = "PageModel.countLiveByApplicationAndName",
query = "SELECT COUNT(p) FROM PageModel p "
+ "WHERE p.name = :name "
+ "AND p.application = :application "
+ "AND p.version = org.libreccm.pagemodel"
+ ".PageModelVersion.LIVE"
)
})
@XmlRootElement(name = "pagemodel") @XmlRootElement(name = "pagemodel")
public class PageModel implements Serializable { public class PageModel implements Serializable {
private static final long serialVersionUID = 7252512839926020978L; private static final long serialVersionUID = 7252512839926020978L;
/** /**
*
* The ID of the entity in the database. * The ID of the entity in the database.
*
*/ */
@Id @Id
@Column(name = "PAGE_MODEL_ID") @Column(name = "PAGE_MODEL_ID")
@ -175,11 +188,9 @@ public class PageModel implements Serializable {
private long pageModelId; private long pageModelId;
/** /**
*
* The UUID of this {@code PageModel}. Please note that this UUID identifies * The UUID of this {@code PageModel}. Please note that this UUID identifies
* the dataset not the model. Therefore the draft and the live version have * the dataset not the model. Therefore the draft and the live version have
* different values for this field. * different values for this field.
*
*/ */
@Column(name = "UUID", length = 255, nullable = false) @Column(name = "UUID", length = 255, nullable = false)
@NotNull @NotNull
@ -257,115 +268,142 @@ public class PageModel implements Serializable {
private List<ContainerModel> containers; private List<ContainerModel> containers;
public PageModel() { public PageModel() {
title = new LocalizedString(); title = new LocalizedString();
description = new LocalizedString(); description = new LocalizedString();
containers = new ArrayList<>(); containers = new ArrayList<>();
} }
public long getPageModelId() { public long getPageModelId() {
return pageModelId; return pageModelId;
} }
protected void setPageModelId(final long pageModelId) { protected void setPageModelId(final long pageModelId) {
this.pageModelId = pageModelId; this.pageModelId = pageModelId;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
protected void setUuid(final String uuid) { protected void setUuid(final String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public String getModelUuid() { public String getModelUuid() {
return modelUuid; return modelUuid;
} }
protected void setModelUuid(final String modelUuid) { protected void setModelUuid(final String modelUuid) {
this.modelUuid = modelUuid; this.modelUuid = modelUuid;
} }
public String getName() { public String getName() {
return name; return name;
} }
public void setName(final String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
public PageModelVersion getVersion() { public PageModelVersion getVersion() {
return version; return version;
} }
protected void setVersion(final PageModelVersion version) { protected void setVersion(final PageModelVersion version) {
this.version = version; this.version = version;
} }
public Date getLastModified() { public Date getLastModified() {
return lastModified; return lastModified;
} }
protected void setLastModified(final Date lastModified) { protected void setLastModified(final Date lastModified) {
this.lastModified = new Date(lastModified.getTime()); this.lastModified = new Date(lastModified.getTime());
} }
public LocalizedString getTitle() { public LocalizedString getTitle() {
return title; return title;
} }
protected void setTitle(final LocalizedString title) { protected void setTitle(final LocalizedString title) {
Objects.requireNonNull(title); Objects.requireNonNull(title);
this.title = title; this.title = title;
} }
public LocalizedString getDescription() { public LocalizedString getDescription() {
return description; return description;
} }
protected void setDescription(final LocalizedString description) { protected void setDescription(final LocalizedString description) {
Objects.requireNonNull(description); Objects.requireNonNull(description);
this.description = description; this.description = description;
} }
public CcmApplication getApplication() { public CcmApplication getApplication() {
return application; return application;
} }
public void setApplication(final CcmApplication application) { public void setApplication(final CcmApplication application) {
this.application = application; this.application = application;
} }
public String getType() { public String getType() {
return type; return type;
} }
public void setType(final String type) { public void setType(final String type) {
this.type = type; this.type = type;
} }
public List<ContainerModel> getContainers() { public List<ContainerModel> getContainers() {
return Collections.unmodifiableList(containers); return Collections.unmodifiableList(containers);
} }
protected void setContainers(final List<ContainerModel> containers) { protected void setContainers(final List<ContainerModel> containers) {
this.containers = new ArrayList<>(containers); this.containers = new ArrayList<>(containers);
} }
protected void addContainer(final ContainerModel container) { protected void addContainer(final ContainerModel container) {
containers.add(container); containers.add(container);
} }
protected void removeContainer(final ContainerModel container) { protected void removeContainer(final ContainerModel container) {
containers.remove(container); containers.remove(container);
} }
protected void clearContainers() { protected void clearContainers() {
containers.clear(); containers.clear();
} }
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 7; int hash = 7;
hash = 71 * hash + (int) (pageModelId ^ (pageModelId >>> 32)); hash = 71 * hash + (int) (pageModelId ^ (pageModelId >>> 32));
hash = 71 * hash + Objects.hashCode(uuid); hash = 71 * hash + Objects.hashCode(uuid);
@ -378,6 +416,7 @@ public class PageModel implements Serializable {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
} }
@ -410,6 +449,7 @@ public class PageModel implements Serializable {
} }
public boolean canEqual(final Object obj) { public boolean canEqual(final Object obj) {
return obj instanceof PageModel; return obj instanceof PageModel;
} }
@ -424,13 +464,13 @@ public class PageModel implements Serializable {
public String toString(final String data) { public String toString(final String data) {
return String.format("%s{ " return String.format("%s{ "
+ "pageModelId = %d, " + "pageModelId = %d, "
+ "uuid = %s, " + "uuid = %s, "
+ "name = \"%s\", " + "name = \"%s\", "
+ "title = %s, " + "title = %s, "
+ "description = %s, " + "description = %s, "
+ "type = \"%s\"" + "type = \"%s\""
+ " }", + " }",
super.toString(), super.toString(),
pageModelId, pageModelId,
uuid, uuid,

View File

@ -85,15 +85,16 @@ public class PageModelManager {
private PageModelRepository pageModelRepo; private PageModelRepository pageModelRepo;
private final Map<String, PageModelComponentModel> components private final Map<String, PageModelComponentModel> components
= new HashMap<>(); = new HashMap<>();
/** /**
* Called by CDI after an instance of this class is created. Initialises the * Called by CDI after an instance of this class is created. Initialises the
* {@link #components} by retrieving the data about all available * {@link #components} by retrieving the data about all available {@link
* {@link ComponentModel}s. * ComponentModel}s.
*/ */
@PostConstruct @PostConstruct
private void init() { private void init() {
LOGGER.debug("Initalising {}...", PageModelManager.class.getName()); LOGGER.debug("Initalising {}...", PageModelManager.class.getName());
final ServiceLoader<CcmModule> modules = ServiceLoader.load( final ServiceLoader<CcmModule> modules = ServiceLoader.load(
@ -127,11 +128,11 @@ public class PageModelManager {
/** /**
* Creates a new {@link PageModel} for the provided application. The method * Creates a new {@link PageModel} for the provided application. The method
* tries to retrieve the appropriate application by using * tries to retrieve the appropriate application by using {@link
* {@link PageModelRepository#findLiveByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}. * PageModelRepository#findLiveByApplicationAndName(org.libreccm.web
* Please note that this method will always return the * .CcmApplication,
* <strong>draft</strong> * java.lang.String)}. Please note that this method will always return the
* version of the page model. * <strong>draft</strong> version of the page model.
* *
* @param name The name of the new page model. Must be unique for the * @param name The name of the new page model. Must be unique for the
* application. * application.
@ -149,16 +150,18 @@ public class PageModelManager {
final String type) { final String type) {
Objects.requireNonNull(application, Objects.requireNonNull(application,
"Can't create a page model for application null"); "Can't create a page model for application "
+ "null");
Objects.requireNonNull(name, "Then name of a Pagemodel can't be null."); Objects.requireNonNull(name, "Then name of a Pagemodel can't be null.");
if (name.isEmpty() if (name.isEmpty()
|| name.matches("\\s*")) { || name.matches("\\s*")) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The name of a PageModel can't be empty."); "The name of a PageModel can't be empty.");
} }
LOGGER.debug( LOGGER.debug(
"Creating new PageModel with name \"{}\" for application \"{}\" and type \"{}\".", "Creating new PageModel with name \"{}\" for application \"{}\" "
+ "and type \"{}\".",
name, name,
application.getPrimaryUrl(), application.getPrimaryUrl(),
type); type);
@ -169,12 +172,12 @@ public class PageModelManager {
if (count > 0) { if (count > 0) {
LOGGER.error("A page model with the name \"{}\" for the " LOGGER.error("A page model with the name \"{}\" for the "
+ "application \"{}\" already exists.", + "application \"{}\" already exists.",
name, name,
application.getPrimaryUrl()); application.getPrimaryUrl());
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"A page model with the name \"%s\" for the application \"%s\" " "A page model with the name \"%s\" for the application \"%s\" "
+ "already exists.", + "already exists.",
name, name,
application.getPrimaryUrl())); application.getPrimaryUrl()));
} }
@ -191,8 +194,8 @@ public class PageModelManager {
/** /**
* Retrieves the draft version of a {@link PageModel}. To invoke this method * Retrieves the draft version of a {@link PageModel}. To invoke this method
* the current user needs a permission granting the * the current user needs a permission granting the {@link
* {@link CoreConstants#PRIVILEGE_ADMIN} privilege. * CoreConstants#PRIVILEGE_ADMIN} privilege.
* *
* @param pageModel The {@link PageModel} for which the draft version is * @param pageModel The {@link PageModel} for which the draft version is
* retrieved. * retrieved.
@ -222,11 +225,12 @@ public class PageModelManager {
* *
* @param pageModel The {@link PageModel} to check for a live version. * @param pageModel The {@link PageModel} to check for a live version.
* *
* @return {@code true} if there is a live version for the provided * @return {@code true} if there is a live version for the provided {@link
* {@link PageModel}, {@code false} otherwise. * PageModel}, {@code false} otherwise.
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public boolean isLive(final PageModel pageModel) { public boolean isLive(final PageModel pageModel) {
final TypedQuery<Boolean> query = entityManager.createNamedQuery( final TypedQuery<Boolean> query = entityManager.createNamedQuery(
"PageModel.hasLiveVersion", Boolean.class); "PageModel.hasLiveVersion", Boolean.class);
query.setParameter("uuid", pageModel.getModelUuid()); query.setParameter("uuid", pageModel.getModelUuid());
@ -242,8 +246,8 @@ public class PageModelManager {
* retrieved. * retrieved.
* *
* @return An {@link Optional} containing the live version of the provided * @return An {@link Optional} containing the live version of the provided
* {@link PageModel} if there is a live version. Otherwise an empty * {@link PageModel} if there is a live version. Otherwise an empty
* {@link Optional} is returned. * {@link Optional} is returned.
*/ */
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public Optional<PageModel> getLiveVersion(final PageModel pageModel) { public Optional<PageModel> getLiveVersion(final PageModel pageModel) {
@ -280,10 +284,13 @@ public class PageModelManager {
final PageModel draftModel = getDraftVersion(pageModel); final PageModel draftModel = getDraftVersion(pageModel);
final PageModel liveModel; final PageModel liveModel;
final boolean isLive;
if (isLive(pageModel)) { if (isLive(pageModel)) {
isLive = true;
liveModel = getLiveVersion(draftModel).get(); liveModel = getLiveVersion(draftModel).get();
} else { } else {
liveModel = new PageModel(); liveModel = new PageModel();
isLive = false;
} }
liveModel.setName(draftModel.getName()); liveModel.setName(draftModel.getName());
@ -312,11 +319,17 @@ public class PageModelManager {
.getContainers() .getContainers()
.stream() .stream()
.map(this::publishContainerModel) .map(this::publishContainerModel)
.forEach(liveContainerModel -> addContainerModel(pageModel, .forEach(liveContainerModel -> addContainerModel(liveModel,
liveContainerModel)); liveContainerModel));
liveModel.setLastModified(new Date()); liveModel.setLastModified(new Date());
pageModelRepo.save(liveModel);
//if (isLive) {
// entityManager.merge(liveModel);
//} else {
// entityManager.persist(liveModel);
//}
LOGGER.debug("Successfully published PageModel \"{}\".", LOGGER.debug("Successfully published PageModel \"{}\".",
liveModel.getName()); liveModel.getName());
return liveModel; return liveModel;
@ -332,18 +345,20 @@ public class PageModelManager {
liveModel.setContainerUuid(draftModel.getContainerUuid()); liveModel.setContainerUuid(draftModel.getContainerUuid());
final Styles draftStyles = draftModel.getStyles(); final Styles draftStyles = draftModel.getStyles();
final Styles liveStyles = new Styles(); if (draftStyles != null) {
liveStyles.setStyleName(draftStyles.getStyleName()); final Styles liveStyles = new Styles();
liveStyles.setRules(draftStyles liveStyles.setStyleName(draftStyles.getStyleName());
.getRules() liveStyles.setRules(draftStyles
.stream() .getRules()
.map(this::publishRule) .stream()
.collect(Collectors.toList())); .map(this::publishRule)
liveStyles.setMediaRules(draftStyles .collect(Collectors.toList()));
.getMediaRules() liveStyles.setMediaRules(draftStyles
.stream() .getMediaRules()
.map(this::publishMediaRule) .stream()
.collect(Collectors.toList())); .map(this::publishMediaRule)
.collect(Collectors.toList()));
}
draftModel draftModel
.getComponents() .getComponents()
@ -360,7 +375,7 @@ public class PageModelManager {
Objects.requireNonNull(draftMediaRule); Objects.requireNonNull(draftMediaRule);
final MediaRule liveMediaRule = new MediaRule(); final MediaRule liveMediaRule = new MediaRule();
final MediaQuery liveMediaQuery = new MediaQuery(); final MediaQuery liveMediaQuery = new MediaQuery();
liveMediaQuery liveMediaQuery
.setMaxWidth(draftMediaRule.getMediaQuery().getMaxWidth()); .setMaxWidth(draftMediaRule.getMediaQuery().getMaxWidth());
@ -370,10 +385,10 @@ public class PageModelManager {
.setMinWidth(draftMediaRule.getMediaQuery().getMinWidth()); .setMinWidth(draftMediaRule.getMediaQuery().getMinWidth());
liveMediaRule.setRules(draftMediaRule liveMediaRule.setRules(draftMediaRule
.getRules() .getRules()
.stream() .stream()
.map(this::publishRule) .map(this::publishRule)
.collect(Collectors.toList())); .collect(Collectors.toList()));
return liveMediaRule; return liveMediaRule;
} }
@ -385,10 +400,10 @@ public class PageModelManager {
final Rule liveRule = new Rule(); final Rule liveRule = new Rule();
liveRule.setSelector(draftRule.getSelector()); liveRule.setSelector(draftRule.getSelector());
liveRule.setProperties(draftRule liveRule.setProperties(draftRule
.getProperties() .getProperties()
.stream() .stream()
.map(this::publishCssProperty) .map(this::publishCssProperty)
.collect(Collectors.toList())); .collect(Collectors.toList()));
return liveRule; return liveRule;
} }
@ -414,9 +429,11 @@ public class PageModelManager {
* @return The live version of the {@link ComponentModel}. * @return The live version of the {@link ComponentModel}.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ComponentModel publishComponentModel(final ComponentModel draftModel) { private ComponentModel publishComponentModel(final ComponentModel
draftModel) {
Objects.requireNonNull(draftModel, "Can't publish ComponentModel null."); Objects.requireNonNull(draftModel,
"Can't publish ComponentModel null.");
LOGGER.debug("Publishing ComponentModel \"{}\"...", LOGGER.debug("Publishing ComponentModel \"{}\"...",
draftModel.getKey()); draftModel.getKey());
@ -447,9 +464,9 @@ public class PageModelManager {
propertyDescriptor.getName(), propertyDescriptor.getName(),
draftModel.getKey()); draftModel.getKey());
final Class<?> propType = propertyDescriptor.getPropertyType(); final Class<?> propType = propertyDescriptor.getPropertyType();
final Method readMethod = propertyDescriptor.getReadMethod(); final Method readMethod = propertyDescriptor.getReadMethod();
final Method writeMethod = propertyDescriptor.getWriteMethod(); final Method writeMethod = propertyDescriptor.getWriteMethod();
if (propertyIsExcluded(propertyDescriptor.getName())) { if (propertyIsExcluded(propertyDescriptor.getName())) {
continue; continue;
@ -460,7 +477,7 @@ public class PageModelManager {
} }
if (propType != null if (propType != null
&& propType.isAssignableFrom(List.class)) { && propType.isAssignableFrom(List.class)) {
try { try {
final List<Object> source = (List<Object>) readMethod final List<Object> source = (List<Object>) readMethod
@ -469,30 +486,31 @@ public class PageModelManager {
target.addAll(source); target.addAll(source);
writeMethod.invoke(draftModel, target); writeMethod.invoke(draftModel, target);
} catch (IllegalAccessException } catch (IllegalAccessException
| IllegalArgumentException | IllegalArgumentException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Map.class)) { && propType.isAssignableFrom(Map.class)) {
final Map<Object, Object> source; final Map<Object, Object> source;
final Map<Object, Object> target; final Map<Object, Object> target;
try { try {
source = (Map<Object, Object>) readMethod.invoke(draftModel); source
= (Map<Object, Object>) readMethod.invoke(draftModel);
target = (Map<Object, Object>) readMethod.invoke(liveModel); target = (Map<Object, Object>) readMethod.invoke(liveModel);
} catch (IllegalAccessException } catch (IllegalAccessException
| IllegalArgumentException | IllegalArgumentException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
source.forEach((key, value) -> target.put(key, value)); source.forEach((key, value) -> target.put(key, value));
} else if (propType != null } else if (propType != null
&& propType.isAssignableFrom(Set.class)) { && propType.isAssignableFrom(Set.class)) {
final Set<Object> source; final Set<Object> source;
final Set<Object> target; final Set<Object> target;
@ -501,8 +519,8 @@ public class PageModelManager {
source = (Set<Object>) readMethod.invoke(draftModel); source = (Set<Object>) readMethod.invoke(draftModel);
target = (Set<Object>) readMethod.invoke(liveModel); target = (Set<Object>) readMethod.invoke(liveModel);
} catch (IllegalAccessException } catch (IllegalAccessException
| IllegalArgumentException | IllegalArgumentException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
@ -513,8 +531,8 @@ public class PageModelManager {
value = readMethod.invoke(draftModel); value = readMethod.invoke(draftModel);
writeMethod.invoke(liveModel, value); writeMethod.invoke(liveModel, value);
} catch (IllegalAccessException } catch (IllegalAccessException
| IllegalArgumentException | IllegalArgumentException
| InvocationTargetException ex) { | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
} }
@ -534,9 +552,10 @@ public class PageModelManager {
* @param name The name of the property. * @param name The name of the property.
* *
* @return {@code true} if the property is excluded from the publishing * @return {@code true} if the property is excluded from the publishing
* process, {@link false} if not. * process, {@link false} if not.
*/ */
private boolean propertyIsExcluded(final String name) { private boolean propertyIsExcluded(final String name) {
final String[] excluded = new String[]{ final String[] excluded = new String[]{
"class", "class",
"uuid", "uuid",
@ -570,7 +589,7 @@ public class PageModelManager {
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeContainerModel(final PageModel pageModel, public void removeContainerModel(final PageModel pageModel,
final ContainerModel container) { final ContainerModel container) {
Objects.requireNonNull(pageModel); Objects.requireNonNull(pageModel);
Objects.requireNonNull(container); Objects.requireNonNull(container);

View File

@ -205,7 +205,7 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
"The name of a page model can't be null or empty."); "The name of a page model can't be null or empty.");
} }
final long count = countLiveByApplicationAndName(application, name); final long count = countDraftByApplicationAndName(application, name);
if (count == 0) { if (count == 0) {
return Optional.empty(); return Optional.empty();
} }

View File

@ -38,8 +38,10 @@ import javax.json.JsonObject;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
@ -151,6 +153,29 @@ public class PageModels {
return mapPageModelToJson(pageModel); return mapPageModelToJson(pageModel);
} }
@POST
@Path(PageModelsApp.PAGE_MODEL_PATH)
@Produces("application/json; charset=utf-8")
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonObject publishPageModel(
@PathParam(PageModelsApp.APP_NAME) final String appPath,
@PathParam(PageModelsApp.PAGE_MODEL_NAME) final String pageModelName,
@FormParam("action") String action) {
if ("publish".equals(action)) {
final CcmApplication app = controller
.findCcmApplication(String.format("/%s/", appPath));
final PageModel pageModel = controller.findPageModel(app,
pageModelName);
pageModelManager.publish(pageModel);
}
return getPageModel(appPath, pageModelName);
}
/** /**
* Creates or updates a {@link PageModel}. * Creates or updates a {@link PageModel}.
* *
@ -259,6 +284,12 @@ public class PageModels {
} else { } else {
lastPublished = 0; lastPublished = 0;
} }
final long lastModified;
if (pageModel.getLastModified() == null) {
lastModified = 0;
} else {
lastModified = pageModel.getLastModified().getTime();
}
return Json return Json
.createObjectBuilder() .createObjectBuilder()
@ -276,6 +307,7 @@ public class PageModels {
.add("version", pageModel.getVersion().toString()) .add("version", pageModel.getVersion().toString())
.add("publicationStatus", .add("publicationStatus",
getPublicationStatus(pageModel).toString()) getPublicationStatus(pageModel).toString())
.add("lastModified", lastModified)
.add("lastPublished", lastPublished) .add("lastPublished", lastPublished)
.build(); .build();
} }
@ -302,10 +334,9 @@ public class PageModels {
|| liveModel.get().getLastModified() == null) { || liveModel.get().getLastModified() == null) {
return PublicationStatus.NEEDS_UPDATE; return PublicationStatus.NEEDS_UPDATE;
} else if (liveModel } else if (draftModel
.get()
.getLastModified() .getLastModified()
.before(draftModel.getLastModified())) { .before(liveModel.get().getLastModified())) {
publicationStatus = PublicationStatus.PUBLISHED; publicationStatus = PublicationStatus.PUBLISHED;
} else { } else {

View File

@ -0,0 +1,2 @@
alter table CCM_CORE.PAGE_MODELS
add column LAST_MODIFIED TIMESTAMP;

View File

@ -0,0 +1,2 @@
alter table CCM_CORE.PAGE_MODELS
add column LAST_MODIFIED TIMESTAMP;

View File

@ -274,14 +274,12 @@ class PageModelComponent
<dd>{this.props.pageModel.version.toString()}</dd> <dd>{this.props.pageModel.version.toString()}</dd>
<dt>Description</dt> <dt>Description</dt>
<dd>{this.props.pageModel.description}</dd> <dd>{this.props.pageModel.description}</dd>
<dt>Last modified</dt>
<dd>{this.getLastModifiedDate()}</dd>
<dt>Last published</dt> <dt>Last published</dt>
<dd>{this.getLastPublishedDate()}</dd> <dd>{this.getLastPublishedDate()}</dd>
<dt>PublicationStatus</dt> <dt>PublicationStatus</dt>
<dd>{this.props.pageModel.publicationStatus}</dd> <dd>{this.props.pageModel.publicationStatus}</dd>
<dt>Publish</dt>
<dd>{this.props.pageModel.publicationStatus === PublicationStatus.NOT_PUBLISHED}</dd>
<dt>Republish</dt>
<dd>{this.props.pageModel.publicationStatus === PublicationStatus.NEEDS_UPDATE}</dd>
</dl> </dl>
<button onClick={(event) => { <button onClick={(event) => {
@ -292,11 +290,11 @@ class PageModelComponent
}); });
}}>Edit }}>Edit
</button> </button>
{this.props.pageModel.publicationStatus === PublicationStatus.NOT_PUBLISHED {this.props.pageModel.publicationStatus === PublicationStatus.NOT_PUBLISHED.toString()
&& <button>Publish</button> && <button onClick={(event) => this.publishPageModel(event)}>Publish</button>
} }
{this.props.pageModel.publicationStatus === PublicationStatus.NEEDS_UPDATE {this.props.pageModel.publicationStatus === PublicationStatus.NEEDS_UPDATE.toString()
&& <button>Republish</button> && <button onClick={(event) => this.publishPageModel(event)}>Republish</button>
} }
</div>; </div>;
} }
@ -317,6 +315,18 @@ class PageModelComponent
}); });
} }
private getLastModifiedDate():string {
if (this.props.pageModel.lastPublished === 0) {
return "";
} else {
const lastModified: Date = new Date();
lastModified.setTime(this.props.pageModel.lastModified);
return lastModified.toISOString();
}
}
private getLastPublishedDate(): string { private getLastPublishedDate(): string {
if (this.props.pageModel.lastPublished === 0) { if (this.props.pageModel.lastPublished === 0) {
@ -426,6 +436,53 @@ class PageModelComponent
}); });
} }
private publishPageModel(event: React.MouseEvent<HTMLButtonElement>): void {
event.preventDefault();
const headers: Headers = new Headers();
//headers.append("Content-Type", "application/json");
headers.append("Content-Type", "application/x-www-form-urlencoded");
//const formData: FormData = new FormData();
//formData.set("action", "publish");
//const data: URLSearchParams = new URLSearchParams();
//data.append("action", "publish");
const init: RequestInit = {
body: "action=publish",
credentials: "same-origin",
headers,
method: "POST",
}
const url: string = `${this.props.dispatcherPrefix}`
+ `/page-models/${this.props.ccmApplication}/`
+ `${this.props.pageModel.name}`
fetch(url, init)
.then((response: Response) => {
if (response.ok) {
this.props.reload();
} else {
this.setState({
...this.state,
errorMsg: `Failed to publish PageModel: `
+ ` ${response.status} ${response.statusText}`,
});
}
})
.catch((error) => {
this.setState({
...this.state,
errorMsg: `Failed to publish PageModel: ${error.message}`,
})
});
}
} }
// interface PageModelEditorProps { // interface PageModelEditorProps {
@ -551,11 +608,12 @@ class PageModelEditor
...this.state, ...this.state,
selectedPageModel: { selectedPageModel: {
description: "", description: "",
lastModified: 0,
lastPublished: 0, lastPublished: 0,
modelUuid: "", modelUuid: "",
name: "", name: "",
pageModelId: 0, pageModelId: 0,
publicationStatus: PublicationStatus.NOT_PUBLISHED, publicationStatus: PublicationStatus.NOT_PUBLISHED.toString(),
title: "", title: "",
type: "", type: "",
uuid: "", uuid: "",

View File

@ -10,7 +10,8 @@ interface PageModel {
type: string; type: string;
uuid: string; uuid: string;
version: PageModelVersion; version: PageModelVersion;
publicationStatus: PublicationStatus; publicationStatus: string;
lastModified: number;
lastPublished: number; lastPublished: number;
} }
@ -22,7 +23,7 @@ enum PageModelVersion {
enum PublicationStatus { enum PublicationStatus {
NOT_PUBLISHED, NOT_PUBLISHED = "NOT_PUBLISHED",
PUBLISHED, PUBLISHED = "PUBLISHED",
NEEDS_UPDATE, NEEDS_UPDATE = "NEEDS_UPDATE",
} }