CCM NG: First part of the Admin UI for PageModels (replacement for JSP based templates)

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5125 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2017-11-20 18:57:18 +00:00
parent 2e6d48c93b
commit 60b716738e
20 changed files with 1911 additions and 24 deletions

View File

@ -0,0 +1,258 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.ui.admin.AdminUiConstants;
import com.arsdigita.util.LockableImpl;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.pagemodel.ComponentModel;
import java.util.Iterator;
import java.util.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class ComponentsTable extends Table {
protected static final int COL_COMPONENT_KEY = 0;
protected static final int COL_COMPONENT_TYPE = 1;
protected static final int COL_EDIT = 2;
protected static final int COL_DELETE = 3;
public ComponentsTable(
final PageModelTab pageModelTab,
final ParameterSingleSelectionModel<String> selectedModelId,
final ParameterSingleSelectionModel<String> selectedComponentId) {
super();
super.setIdAttr("pageModelComponentModelsTable");
super.setEmptyView(new Label(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.none",
AdminUiConstants.ADMIN_BUNDLE)));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_COMPONENT_KEY,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.cols.key.heading",
AdminUiConstants.ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_COMPONENT_TYPE,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.cols.type.heading",
AdminUiConstants.ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.cols.edit.heading",
AdminUiConstants.ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_DELETE,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.cols.delete.heading",
AdminUiConstants.ADMIN_BUNDLE))));
columnModel.get(COL_EDIT).setCellRenderer(
new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final ControlLink link = new ControlLink((Component) value);
return link;
}
});
columnModel.get(COL_DELETE).setCellRenderer(
new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
final ControlLink link = new ControlLink((Component) value);
link.setConfirmation(new GlobalizedMessage(
"ui.admin.pagemodels.componentmodels.cols.delete.confirmation",
AdminUiConstants.ADMIN_BUNDLE));
return link;
}
});
super.addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
final String key = (String) event.getRowKey();
switch (event.getColumn()) {
case COL_EDIT:
selectedComponentId.setSelectedKey(state, key);
pageModelTab.showComponentForm(state);
break;
case COL_DELETE:
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelsController controller = cdiUtil
.findBean(PageModelsController.class);
controller.removeComponentModel(
Long.parseLong(selectedModelIdStr),
Long.parseLong(key));
break;
default:
throw new IllegalArgumentException(
"Invalid value for column");
}
}
@Override
public void headSelected(final TableActionEvent event) {
//Nothing
}
});
super.setModelBuilder(new PageModelComponentsTableModelBuilder(
selectedModelId));
}
private class PageModelComponentsTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
private final ParameterSingleSelectionModel<String> selectedModelId;
public PageModelComponentsTableModelBuilder(
final ParameterSingleSelectionModel<String> selectedModelId) {
this.selectedModelId = selectedModelId;
}
@Override
public TableModel makeModel(final Table table,
final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelsController controller = cdiUtil
.findBean(PageModelsController.class);
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
final List<ComponentModel> components = controller
.retrieveComponents(Long.parseLong(selectedModelIdStr));
return new PageModelComponentsTableModel(components);
}
}
private class PageModelComponentsTableModel implements TableModel {
private final Iterator<ComponentModel> iterator;
private ComponentModel currentComponent;
public PageModelComponentsTableModel(
final List<ComponentModel> components) {
iterator = components.iterator();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public boolean nextRow() {
if (iterator.hasNext()) {
currentComponent = iterator.next();
return true;
} else {
return false;
}
}
@Override
public Object getElementAt(final int columnIndex) {
switch (columnIndex) {
case ComponentsTable.COL_COMPONENT_KEY:
return currentComponent.getKey();
case ComponentsTable.COL_COMPONENT_TYPE:
return currentComponent.getClass().getName();
case ComponentsTable.COL_EDIT:
return new Label(new GlobalizedMessage(
"ui.admin.pagemodels.components.edit",
AdminUiConstants.ADMIN_BUNDLE));
case ComponentsTable.COL_DELETE:
return new Label(new GlobalizedMessage(
"ui.admin.pagemodels.components.delete",
AdminUiConstants.ADMIN_BUNDLE));
default:
throw new IllegalArgumentException(
"Not a valid column index");
}
}
@Override
public Object getKeyAt(final int columnIndex) {
return currentComponent.getComponentModelId();
}
}
}

View File

@ -0,0 +1,133 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.PropertySheet;
import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.ui.admin.AdminUiConstants;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.modules.ModuleManager;
import org.libreccm.pagemodel.ComponentModels;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelRepository;
import java.util.TooManyListenersException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelDetails extends BoxPanel {
public PageModelDetails(
final PageModelTab pageModelTab,
final ParameterSingleSelectionModel<String> selectedModelId,
final ParameterSingleSelectionModel<String> selectedComponentId) {
super(BoxPanel.VERTICAL);
final ActionLink backLink = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.details.back",
AdminUiConstants.ADMIN_BUNDLE));
backLink.setClassAttr("back-link");
backLink.addActionListener(event -> {
selectedModelId.clearSelection(event.getPageState());
pageModelTab.showPageModelsTable(event.getPageState());
});
super.add(backLink);
final Label heading = new Label();
heading.setClassAttr("heading");
heading.addPrintListener(event -> {
final PageState state = event.getPageState();
final Label target = (Label) event.getTarget();
final PageModelRepository pageModelRepo = CdiUtil
.createCdiUtil()
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelId.getSelectedKey(state)))
.get();
target.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.details.heading",
AdminUiConstants.ADMIN_BUNDLE,
new String[]{pageModel.getName()}));
});
super.add(heading);
final PropertySheet propertySheet = new PropertySheet(
new PageModelPropertySheetModelBuilder(selectedModelId));
super.add(propertySheet);
final ActionLink editProperties = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.details.edit_properties",
AdminUiConstants.ADMIN_BUNDLE));
editProperties.addActionListener(event -> {
pageModelTab.showPageModelForm(event.getPageState());
});
super.add(editProperties);
final ActionLink addComponent = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.details.add_component",
AdminUiConstants.ADMIN_BUNDLE));
addComponent.addActionListener(event -> {
//pageModelTab.showNewComponentForm(state, componentModelClass);
});
super.add(addComponent);
final ComponentsTable componentsTable
= new ComponentsTable(
pageModelTab, selectedModelId, selectedComponentId);
super.add(componentsTable);
}
private class AddComponentForm extends Form {
private final SingleSelect selectType;
public AddComponentForm() {
super("pagemodel_add_component_form");
selectType = new SingleSelect("select_component_type");
try {
selectType.addPrintListener(event -> {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ComponentModels componentModels = cdiUtil
.findBean(ComponentModels.class);
});
} catch (TooManyListenersException ex) {
throw new UnexpectedErrorException(ex);
}
}
}
}

View File

@ -0,0 +1,371 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.SingleSelect;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.ui.admin.AdminUiConstants;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelManager;
import org.libreccm.pagemodel.PageModelRepository;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.CcmApplication;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.TooManyListenersException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelForm extends Form {
private static final String MODEL_APPLICATION = "application";
private static final String MODEL_NAME = "model_name";
private static final String MODEL_TITLE = "model_title";
private static final String MODEL_DESC = "model_desc";
private final PageModelTab pageModelTab;
private final ParameterSingleSelectionModel<String> selectedModelId;
private final TextField nameField;
private final TextField titleField;
private final TextArea descArea;
private final SingleSelect applicationSelect;
private final SaveCancelSection saveCancelSection;
public PageModelForm(
final PageModelTab pageModelTab,
final ParameterSingleSelectionModel<String> selectedModelId) {
super("pagemodelsform");
this.pageModelTab = pageModelTab;
this.selectedModelId = selectedModelId;
final Label heading = new Label(event -> {
final PageState state = event.getPageState();
final Label target = (Label) event.getTarget();
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
if (selectedModelIdStr == null || selectedModelIdStr.isEmpty()) {
target.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.create_new",
AdminUiConstants.ADMIN_BUNDLE));
} else {
target.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.edit",
AdminUiConstants.ADMIN_BUNDLE));
}
});
heading.setClassAttr("heading");
super.add(heading);
nameField = new TextField(MODEL_NAME);
nameField.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.name",
AdminUiConstants.ADMIN_BUNDLE));
super.add(nameField);
titleField = new TextField(MODEL_TITLE);
titleField.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.title",
AdminUiConstants.ADMIN_BUNDLE));
super.add(titleField);
descArea = new TextArea(MODEL_DESC);
descArea.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.desc",
AdminUiConstants.ADMIN_BUNDLE));
super.add(descArea);
applicationSelect = new SingleSelect(MODEL_APPLICATION);
applicationSelect.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.application",
AdminUiConstants.ADMIN_BUNDLE));
super.add(applicationSelect);
try {
applicationSelect.addPrintListener(event -> {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ApplicationRepository applicationRepo = cdiUtil
.findBean(ApplicationRepository.class);
final SingleSelect target = (SingleSelect) event.getTarget();
target.clearOptions();
final List<CcmApplication> applications = applicationRepo
.findAll();
applications.sort((app1, app2) -> {
return app1.getPrimaryUrl().compareTo(app2.getPrimaryUrl());
});
for (final CcmApplication app : applications) {
target.addOption(new Option(app.getPrimaryUrl(),
new Text(app.getPrimaryUrl())));
}
});
} catch (TooManyListenersException ex) {
throw new UnexpectedErrorException(ex);
}
super.add(applicationSelect);
saveCancelSection = new SaveCancelSection();
super.add(saveCancelSection);
super.addValidationListener(new ValidationListener());
super.addInitListener(new InitListener());
super.addProcessListener(new ProcessListener());
}
private class ValidationListener implements FormValidationListener {
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = event.getFormData();
final String nameValue = data.getString(MODEL_NAME);
final String titleValue = data.getString(MODEL_TITLE);
final String appValue = data.getString(MODEL_APPLICATION);
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
final boolean modelEditedOrNew;
if (selectedModelIdStr == null || selectedModelIdStr.isEmpty()) {
modelEditedOrNew = true;
} else {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ConfigurationManager confManager = cdiUtil
.findBean(ConfigurationManager.class);
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelIdStr))
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %s in the database.",
selectedModelIdStr)));
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
final boolean nameEdited = !pageModel
.getName()
.equals(nameValue);
final boolean titleEdited = !pageModel
.getTitle()
.getValue(kernelConfig.getDefaultLocale())
.equals(titleValue);
final boolean appEdited = !pageModel
.getApplication()
.getPrimaryUrl()
.equals(appValue);
modelEditedOrNew = nameEdited || titleEdited || appEdited;
}
if (modelEditedOrNew) {
if (nameValue == null
|| nameValue.isEmpty()
|| nameValue.matches("\\s*")) {
data.addError(MODEL_NAME,
new GlobalizedMessage(
"ui.admin.pagemodels.name.error.empty",
AdminUiConstants.ADMIN_BUNDLE));
}
if (titleValue == null
|| titleValue.isEmpty()
|| titleValue.matches("\\s*")) {
data.addError(MODEL_TITLE,
new GlobalizedMessage(
"ui.admin.pagemodels.title.error.empty",
AdminUiConstants.ADMIN_BUNDLE));
}
if (appValue == null
|| appValue.isEmpty()
|| appValue.matches("\\s*")) {
data.addError(MODEL_TITLE,
new GlobalizedMessage(
"ui.admin.pagemodels.application.error.empty",
AdminUiConstants.ADMIN_BUNDLE));
} else {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ApplicationRepository appRepo = cdiUtil
.findBean(ApplicationRepository.class);
final Optional<CcmApplication> application = appRepo
.retrieveApplicationForPath(appValue);
if (!application.isPresent()) {
data.addError(MODEL_TITLE,
new GlobalizedMessage(
"ui.admin.pagemodels.application.error.invalid",
AdminUiConstants.ADMIN_BUNDLE));
}
}
}
}
}
}
private class InitListener implements FormInitListener {
@Override
public void init(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
if (selectedModelIdStr != null && !selectedModelIdStr.isEmpty()) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final ConfigurationManager confManager = cdiUtil
.findBean(ConfigurationManager.class);
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
final Locale defaultLocale = kernelConfig.getDefaultLocale();
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelIdStr))
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %s in the database.",
selectedModelIdStr)));
nameField.setValue(state, pageModel.getName());
titleField.setValue(state,
pageModel.getTitle().getValue(defaultLocale));
descArea
.setValue(state,
pageModel.getDescription().getValue(defaultLocale));
applicationSelect
.setValue(state,
pageModel.getApplication().getPrimaryUrl());
}
}
}
private class ProcessListener implements FormProcessListener {
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = event.getFormData();
final String nameValue = data.getString(MODEL_NAME);
final String titleValue = data.getString(MODEL_TITLE);
final String descValue = data.getString(MODEL_DESC);
final String appValue = data.getString(MODEL_APPLICATION);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final ConfigurationManager confManager = cdiUtil
.findBean(ConfigurationManager.class);
final ApplicationRepository appRepo = cdiUtil
.findBean(ApplicationRepository.class);
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
final Locale defaultLocale = kernelConfig.getDefaultLocale();
final String selectedModelIdStr = selectedModelId
.getSelectedKey(state);
final PageModel pageModel;
if (selectedModelIdStr == null || selectedModelIdStr.isEmpty()) {
pageModel = new PageModel();
} else {
pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelIdStr))
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %s in the database.",
selectedModelIdStr)));
}
pageModel.setName(nameValue);
pageModel.getTitle().addValue(defaultLocale, titleValue);
pageModel.getDescription().addValue(defaultLocale, descValue);
final CcmApplication application = appRepo
.retrieveApplicationForPath(appValue)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No CcmApplication with primary URL \"%s\" in the "
+ "database.",
appValue)));
pageModel.setApplication(application);
pageModelRepo.save(pageModel);
}
pageModelTab.showPageModelDetails(state);
}
}
}

View File

@ -0,0 +1,112 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.PropertySheetModel;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.ui.admin.AdminUiConstants;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.pagemodel.PageModel;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelPropertySheetModel implements PropertySheetModel {
private static enum PageModelProperty {
MODEL_NAME,
MODEL_TITLE,
MODEL_APPLICATION,
MODEL_DESC
}
private final PageModel pageModel;
private final Iterator<PageModelProperty> propertyIterator;
private PageModelProperty currentProperty;
public PageModelPropertySheetModel(final PageModel pageModel) {
this.pageModel = pageModel;
propertyIterator = Arrays
.asList(PageModelProperty.values())
.iterator();
}
@Override
public boolean nextRow() {
if (pageModel == null) {
return false;
}
if (propertyIterator.hasNext()) {
currentProperty = propertyIterator.next();
return true;
} else {
return false;
}
}
@Override
public String getLabel() {
return currentProperty.toString();
}
@Override
public GlobalizedMessage getGlobalizedLabel() {
final String key = String
.join("",
"ui.admin.pagemodels.details.",
currentProperty.toString().toLowerCase());
return new GlobalizedMessage(key, AdminUiConstants.ADMIN_BUNDLE);
}
@Override
public String getValue() {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final ConfigurationManager confManager = cdiUtil
.findBean(ConfigurationManager.class);
final KernelConfig kernelConfig = confManager
.findConfiguration(KernelConfig.class);
final Locale defaultLocale = kernelConfig.getDefaultLocale();
switch (currentProperty) {
case MODEL_APPLICATION:
return pageModel.getApplication().getPrimaryUrl();
case MODEL_DESC:
return pageModel.getDescription().getValue(defaultLocale);
case MODEL_NAME:
return pageModel.getName();
case MODEL_TITLE:
return pageModel.getTitle().getValue(defaultLocale);
default:
return "";
}
}
}

View File

@ -0,0 +1,66 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.PropertySheet;
import com.arsdigita.bebop.PropertySheetModel;
import com.arsdigita.util.LockableImpl;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelRepository;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelPropertySheetModelBuilder
extends LockableImpl
implements com.arsdigita.bebop.PropertySheetModelBuilder {
private final ParameterSingleSelectionModel<String> selectedModelId;
public PageModelPropertySheetModelBuilder(
final ParameterSingleSelectionModel<String> selectedModelId) {
this.selectedModelId = selectedModelId;
}
@Override
public PropertySheetModel makeModel(final PropertySheet sheet,
final PageState state) {
final String selectedModelIdStr = selectedModelId.getSelectedKey(
state);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelIdStr))
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %s in the database.",
selectedModelIdStr)));
return new PageModelPropertySheetModel(pageModel);
}
}

View File

@ -0,0 +1,190 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.MetaForm;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.LayoutPanel;
import com.arsdigita.ui.admin.AdminUiConstants;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.pagemodel.ComponentModel;
import java.lang.reflect.InvocationTargetException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class PageModelTab extends LayoutPanel {
private final ParameterSingleSelectionModel<String> selectedModelId;
private final ParameterSingleSelectionModel<String> selectedComponentId;
private final ActionLink addNewModel;
private final PageModelsTable pageModelsTable;
private final PageModelDetails pageModelDetails;
private final PageModelForm pageModelForm;
private final MetaForm componentForm;
private Class<? extends ComponentModel> componentModelClass;
public PageModelTab() {
super();
super.setClassAttr("sidebarNavPanel");
final BoxPanel left = new BoxPanel(BoxPanel.VERTICAL);
selectedModelId = new ParameterSingleSelectionModel<>(
new StringParameter("selected_pagemodel_id"));
selectedComponentId = new ParameterSingleSelectionModel<>(
new StringParameter(("selected_pagemodel_component_id")));
pageModelsTable = new PageModelsTable(this, selectedModelId);
pageModelDetails = new PageModelDetails(this,
selectedModelId,
selectedComponentId);
pageModelForm = new PageModelForm(this, selectedModelId);
addNewModel = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.add_new_pagemodel_link",
AdminUiConstants.ADMIN_BUNDLE));
addNewModel.addActionListener(event -> {
showPageModelForm(event.getPageState());
});
componentForm = new MetaForm("componentsForm") {
@Override
public Form buildForm(final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelsController controller = cdiUtil
.findBean(PageModelsController.class);
try {
if (selectedComponentId.getSelectedKey(state) == null
|| selectedComponentId.getSelectedKey(state)
.isEmpty()) {
final Class<? extends Form> formClass = controller
.getComponentModelForm(componentModelClass);
formClass
.getDeclaredConstructor()
.newInstance();
} else {
final Class<? extends Form> formClass = controller
.getComponentModelForm(Long
.parseLong(selectedComponentId
.getSelectedKey(state)));
return formClass
.getDeclaredConstructor(
ParameterSingleSelectionModel.class)
.newInstance(selectedComponentId);
}
} catch (InstantiationException
| InvocationTargetException
| IllegalAccessException
| NoSuchMethodException ex) {
throw new UnexpectedErrorException(ex);
}
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
};
final BoxPanel right = new BoxPanel(BoxPanel.VERTICAL);
right.add(addNewModel);
right.add(pageModelsTable);
right.add(pageModelDetails);
right.add(pageModelForm);
right.add(componentForm);
setLeft(left);
setRight(right);
}
@Override
public void register(final Page page) {
super.register(page);
page.addGlobalStateParam(selectedModelId.getStateParameter());
page.setVisibleDefault(addNewModel, true);
page.setVisibleDefault(pageModelsTable, true);
page.setVisibleDefault(pageModelDetails, false);
page.setVisibleDefault(pageModelForm, false);
page.setVisibleDefault(componentForm, false);
}
protected void showNewComponentForm(
final PageState state,
final Class<? extends ComponentModel> componentModelClass) {
this.componentModelClass = componentModelClass;
showComponentForm(state);
}
protected void showComponentForm(final PageState state) {
addNewModel.setVisible(state, false);
pageModelsTable.setVisible(state, false);
pageModelDetails.setVisible(state, true);
pageModelForm.setVisible(state, false);
componentForm.setVisible(state, false);
}
protected void showPageModelDetails(final PageState state) {
addNewModel.setVisible(state, false);
pageModelsTable.setVisible(state, false);
pageModelDetails.setVisible(state, true);
pageModelForm.setVisible(state, false);
componentForm.setVisible(state, false);
}
protected void showPageModelForm(final PageState state) {
addNewModel.setVisible(state, false);
pageModelsTable.setVisible(state, false);
pageModelDetails.setVisible(state, false);
pageModelForm.setVisible(state, true);
componentForm.setVisible(state, false);
}
protected void showPageModelsTable(final PageState state) {
addNewModel.setVisible(state, true);
pageModelsTable.setVisible(state, true);
pageModelDetails.setVisible(state, false);
pageModelForm.setVisible(state, false);
componentForm.setVisible(state, false);
}
}

View File

@ -0,0 +1,179 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.Form;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.pagemodel.ComponentModelRepository;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelComponentModel;
import org.libreccm.pagemodel.PageModelManager;
import org.libreccm.pagemodel.PageModelRepository;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.CcmApplication;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
class PageModelsController implements Serializable {
private static final long serialVersionUID = -5105462163244688201L;
@Inject
private ApplicationRepository applicationRepo;
@Inject
private ComponentModelRepository componentModelRepo;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private PageModelManager pageModelManager;
@Inject
private PageModelRepository pageModelRepo;
@Transactional(Transactional.TxType.REQUIRED)
protected List<PageModelsTableRow> findPageModels() {
return pageModelRepo
.findAll()
.stream()
.map(this::buildRow)
.sorted()
.collect(Collectors.toList());
}
@Transactional(Transactional.TxType.REQUIRED)
protected boolean isUnique(final long applicationId,
final String name) {
final CcmApplication application = applicationRepo
.findById(applicationId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No CcmApplication with ID %d in the database.",
applicationId)));
return !pageModelRepo
.findByApplicationAndName(application, name)
.isPresent();
}
@Transactional(Transactional.TxType.REQUIRED)
protected void deletePageModel(final long pageModelId) {
final PageModel model = pageModelRepo
.findById(pageModelId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %d in the database.",
pageModelId)));
pageModelRepo.delete(model);
}
private PageModelsTableRow buildRow(final PageModel model) {
final PageModelsTableRow row = new PageModelsTableRow();
row.setModelId(model.getPageModelId());
row.setName(model.getName());
row.setTitle(globalizationHelper
.getValueFromLocalizedString(model.getTitle()));
row.setDescription(globalizationHelper
.getValueFromLocalizedString(model.getDescription()));
row.setApplicationName(model.getApplication().getPrimaryUrl());
row.setLive(pageModelManager.isLive(model));
return row;
}
protected Class<? extends Form> getComponentModelForm(
final long componentModelId) {
final ComponentModel componentModel = componentModelRepo
.findById(componentModelId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No ComponentModel with ID %d in the database.",
componentModelId)));
final Class<? extends ComponentModel> clazz = componentModel
.getClass();
return getComponentModelForm(clazz);
}
protected Class<? extends Form> getComponentModelForm(
final Class<? extends ComponentModel> clazz) {
if (clazz.isAnnotationPresent(PageModelComponentModel.class)) {
final PageModelComponentModel annotation = clazz
.getAnnotation(PageModelComponentModel.class);
return annotation.editor();
} else {
return null;
}
}
@Transactional(Transactional.TxType.REQUIRED)
protected List<ComponentModel> retrieveComponents(final long pageModelId) {
final PageModel model = pageModelRepo
.findById(pageModelId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %d in the database.",
pageModelId)));
return model.getComponents();
}
@Transactional(Transactional.TxType.REQUIRED)
protected void removeComponentModel(final long pageModelId,
final long componentModelId) {
final PageModel model = pageModelRepo
.findById(pageModelId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No PageModel with ID %d in the database.",
pageModelId)));
final ComponentModel componentModel = componentModelRepo
.findById(componentModelId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No ComponentModel with ID %d in the database.",
componentModelId)));
pageModelManager.removeComponentModel(model, componentModel);
}
}

View File

@ -0,0 +1,256 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.ui.admin.AdminUiConstants;
import com.arsdigita.util.LockableImpl;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.Iterator;
import java.util.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelsTable extends Table {
public static final int COL_MODEL_APPLICATION = 0;
public static final int COL_MODEL_NAME = 1;
public static final int COL_MODEL_TITLE = 2;
public static final int COL_MODEL_DESC = 3;
public static final int COL_REMOVE = 4;
public PageModelsTable(
final PageModelTab parent,
final ParameterSingleSelectionModel<String> selectedPageModelId) {
super();
super.setIdAttr("pageModelsTable");
super.setStyleAttr("wdith: 30em");
setEmptyView(new Label(
new GlobalizedMessage("ui.admin.pagemodels.table.empty_view",
AdminUiConstants.ADMIN_BUNDLE)));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_MODEL_APPLICATION,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.headers.application",
AdminUiConstants.ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_MODEL_NAME,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.headers.name",
AdminUiConstants.ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_MODEL_TITLE,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.headers.title",
AdminUiConstants.ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_MODEL_DESC,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.headers.desc",
AdminUiConstants.ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_REMOVE,
new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.headers.remove",
AdminUiConstants.ADMIN_BUNDLE))
));
columnModel
.get(COL_MODEL_NAME)
.setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new ControlLink((String) value);
}
});
columnModel
.get(COL_REMOVE)
.setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (value == null) {
return new Text("");
} else {
final ControlLink link = new ControlLink(
(Component) value);
link.setConfirmation(new GlobalizedMessage(
"ui.admin.pagemodels.delete.confirm",
AdminUiConstants.ADMIN_BUNDLE));
return link;
}
}
});
super.addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event)
throws FormProcessException {
final PageState state = event.getPageState();
final String key = (String) event.getRowKey();
switch (event.getColumn()) {
case COL_MODEL_NAME:
selectedPageModelId.setSelectedKey(state, key);
parent.showPageModelDetails(state);
break;
case COL_REMOVE:
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelsController controller = cdiUtil
.findBean(PageModelsController.class);
controller.deletePageModel(Long.parseLong(key));
break;
default:
throw new IllegalArgumentException(
"Invalid value for column.");
}
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void headSelected(final TableActionEvent event) {
// Nothing
}
});
super.setModelBuilder(new PageModelsTableModelBuilder());
}
private class PageModelsTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
@Override
public TableModel makeModel(final Table table,
final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelsController controller = cdiUtil
.findBean(PageModelsController.class);
return new PageModelsTableModel(controller.findPageModels());
}
}
private class PageModelsTableModel implements TableModel {
private final Iterator<PageModelsTableRow> iterator;
private PageModelsTableRow currentRow;
public PageModelsTableModel(final List<PageModelsTableRow> rows) {
iterator = rows.iterator();
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public boolean nextRow() {
if (iterator.hasNext()) {
currentRow = iterator.next();
return true;
} else {
return false;
}
}
@Override
public Object getElementAt(final int columnIndex) {
switch (columnIndex) {
case COL_MODEL_APPLICATION:
return currentRow.getApplicationName();
case COL_MODEL_DESC:
return currentRow.getDescription();
case COL_MODEL_NAME:
return currentRow.getName();
case COL_MODEL_TITLE:
return currentRow.getTitle();
case COL_REMOVE:
return new Label(new GlobalizedMessage(
"ui.admin.pagemodels.table.columns.remove.label",
AdminUiConstants.ADMIN_BUNDLE));
default:
throw new IllegalArgumentException("No a valid column index");
}
}
@Override
public Object getKeyAt(final int columnIndex) {
return currentRow.getModelId();
}
}
}

View File

@ -0,0 +1,110 @@
/*
* 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 com.arsdigita.ui.admin.pagemodels;
import java.io.Serializable;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class PageModelsTableRow implements Comparable<PageModelsTableRow>,
Serializable {
private static final long serialVersionUID = 7497498047332094014L;
private long modelId;
private String name;
private boolean live;
private String title;
private String description;
private String applicationName;
public long getModelId() {
return modelId;
}
public void setModelId(final long modelId) {
this.modelId = modelId;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public boolean isLive() {
return live;
}
public void setLive(final boolean live) {
this.live = live;
}
public String getTitle() {
return title;
}
public void setTitle(final String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(final String applicationName) {
this.applicationName = applicationName;
}
@Override
public int compareTo(final PageModelsTableRow other) {
int result;
result = applicationName.compareTo(other.getApplicationName());
if (result != 0) {
return result;
}
result = name.compareTo(other.getName());
if (result != 0) {
return result;
}
return title.compareTo(other.getTitle());
}
}

View File

@ -52,7 +52,7 @@ import static com.arsdigita.ui.admin.AdminUiConstants.*;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class SitesForm extends Form { class SitesForm extends Form {
private static final String DOMAIN_OF_SITE = "domainOfSite"; private static final String DOMAIN_OF_SITE = "domainOfSite";
private static final String DEFAULT_SITE = "defaultSite"; private static final String DEFAULT_SITE = "defaultSite";

View File

@ -47,7 +47,7 @@ import static com.arsdigita.ui.admin.AdminUiConstants.*;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class SitesTable extends Table { class SitesTable extends Table {
public static final int COL_SITE_DOMAIN = 0; public static final int COL_SITE_DOMAIN = 0;
public static final int COL_IS_DEFAULT_SITE = 1; public static final int COL_IS_DEFAULT_SITE = 1;

View File

@ -48,56 +48,58 @@ class RoleDetails extends BoxPanel {
final ActionLink backLink = new ActionLink(new GlobalizedMessage( final ActionLink backLink = new ActionLink(new GlobalizedMessage(
"ui.admin.role_details.back", ADMIN_BUNDLE)); "ui.admin.role_details.back", ADMIN_BUNDLE));
backLink.setClassAttr("back-link"); backLink.setClassAttr("back-link");
backLink.addActionListener(e -> { backLink.addActionListener(event -> {
roleAdmin.hideRoleDetails(e.getPageState()); roleAdmin.hideRoleDetails(event.getPageState());
}); });
add(backLink); super.add(backLink);
final Label heading = new Label(); final Label heading = new Label();
heading.setClassAttr("heading"); heading.setClassAttr("heading");
heading.addPrintListener(e -> { heading.addPrintListener(event -> {
final PageState state = e.getPageState(); final PageState state = event.getPageState();
final Label target = (Label) e.getTarget(); final Label target = (Label) event.getTarget();
final RoleRepository roleRepository = CdiUtil.createCdiUtil() final RoleRepository roleRepository = CdiUtil
.createCdiUtil()
.findBean(RoleRepository.class); .findBean(RoleRepository.class);
final Role role = roleRepository.findById(Long.parseLong( final Role role = roleRepository
selectedRoleId.getSelectedKey(state))).get(); .findById(Long.parseLong(selectedRoleId.getSelectedKey(state)))
.get();
target.setLabel(new GlobalizedMessage( target.setLabel(new GlobalizedMessage(
"ui.admin.role_details.heading", "ui.admin.role_details.heading",
ADMIN_BUNDLE, ADMIN_BUNDLE,
new String[]{role.getName()})); new String[]{role.getName()}));
}); });
add(heading); super.add(heading);
final PropertySheet propertySheet = new PropertySheet( final PropertySheet propertySheet = new PropertySheet(
new RolePropertySheetModelBuilder(selectedRoleId)); new RolePropertySheetModelBuilder(selectedRoleId));
add(propertySheet); super.add(propertySheet);
final BoxPanel links = new BoxPanel(BoxPanel.HORIZONTAL); final BoxPanel links = new BoxPanel(BoxPanel.HORIZONTAL);
final ActionLink editProperties = new ActionLink(new GlobalizedMessage( final ActionLink editProperties = new ActionLink(new GlobalizedMessage(
"ui.admin.role_details.edit_properties", ADMIN_BUNDLE)); "ui.admin.role_details.edit_properties", ADMIN_BUNDLE));
editProperties.addActionListener(e -> { editProperties.addActionListener(event -> {
roleAdmin.showRoleForm(e.getPageState()); roleAdmin.showRoleForm(event.getPageState());
}); });
links.add(editProperties); links.add(editProperties);
final ActionLink manageMembers = new ActionLink(new GlobalizedMessage( final ActionLink manageMembers = new ActionLink(new GlobalizedMessage(
"ui.admin.role_details.manage_members", ADMIN_BUNDLE)); "ui.admin.role_details.manage_members", ADMIN_BUNDLE));
manageMembers.addActionListener(e -> { manageMembers.addActionListener(event -> {
roleAdmin.showRoleMembersPanel(e.getPageState()); roleAdmin.showRoleMembersPanel(event.getPageState());
}); });
links.add(manageMembers); links.add(manageMembers);
final ActionLink managePermissions = new ActionLink(new GlobalizedMessage( final ActionLink managePermissions = new ActionLink(new GlobalizedMessage(
"ui.admin.role_details.manage_permissions", ADMIN_BUNDLE)); "ui.admin.role_details.manage_permissions", ADMIN_BUNDLE));
managePermissions.addActionListener(e -> { managePermissions.addActionListener(event -> {
roleAdmin.showRolePermissionsPanel(e.getPageState()); roleAdmin.showRolePermissionsPanel(event.getPageState());
}); });
links.add(managePermissions); links.add(managePermissions);
add(links); super.add(links);
} }
} }

View File

@ -0,0 +1,66 @@
/*
* 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.libreccm.pagemodel;
import org.libreccm.modules.CcmModule;
import org.libreccm.modules.Module;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ApplicationScoped
public class ComponentModels {
private final List<PageModelComponentModel> availableComponentModels = new ArrayList<>();
@PostConstruct
private void init() {
final ServiceLoader<CcmModule> modules = ServiceLoader
.load(CcmModule.class);
for (final CcmModule module : modules) {
final Module moduleData = module
.getClass()
.getAnnotation(Module.class);
final PageModelComponentModel[] componentModels = moduleData
.pageModelComponentModels();
for(final PageModelComponentModel componentModel : componentModels) {
availableComponentModels.add(componentModel);
}
}
}
public List<PageModelComponentModel> findAvailableComponentModels() {
return Collections.unmodifiableList(availableComponentModels);
}
}

View File

@ -270,7 +270,7 @@ public class PageModel implements Serializable {
return application; return application;
} }
protected void setApplication(final CcmApplication application) { public void setApplication(final CcmApplication application) {
this.application = application; this.application = application;
} }

View File

@ -0,0 +1,83 @@
/*
* 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.libreccm.theming.xslt;
import org.libreccm.theming.ThemeProvider;
import org.libreccm.theming.ThemeVersion;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class CcmUriResolver implements URIResolver {
private final String theme;
private final ThemeVersion version;
private final ThemeProvider themeProvider;
protected CcmUriResolver(final String theme,
final ThemeVersion version,
final ThemeProvider themeProvider) {
Objects.requireNonNull(theme);
Objects.requireNonNull(version);
Objects.requireNonNull(themeProvider);
this.theme = theme;
this.version = version;
this.themeProvider = themeProvider;
}
@Override
public Source resolve(final String href,
final String base) throws TransformerException {
final String path;
if (base == null) {
path = href;
} else {
path = String.join("/", href, base);
}
final InputStream inputStream = themeProvider
.getThemeFileAsStream(theme, version, path)
.orElseThrow(() -> new TransformerException(String
.format("Failed to resolve URI with href = \"%s\" and base = \"%s\" "
+ "for theme \"%s\" (version = \"%s\" using "
+ "ThemeProvider \"%s\".",
href,
base,
theme,
version,
themeProvider.getClass().getName())));
return new StreamSource(inputStream);
}
}

View File

@ -39,6 +39,7 @@ import javax.xml.parsers.ParserConfigurationException;
import static org.libreccm.theming.ThemeConstants.*; import static org.libreccm.theming.ThemeConstants.*;
import org.libreccm.theming.ThemeVersion;
import org.libreccm.theming.manifest.ThemeTemplate; import org.libreccm.theming.manifest.ThemeTemplate;
import java.io.InputStream; import java.io.InputStream;
@ -49,6 +50,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Optional; import java.util.Optional;
import javax.xml.transform.Result; import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
@ -59,7 +61,7 @@ import javax.xml.transform.stream.StreamSource;
/** /**
* A {@link ThemeProcessor} implementation for XSLT based themes. * A {@link ThemeProcessor} implementation for XSLT based themes.
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
@RequestScoped @RequestScoped
@ -147,10 +149,13 @@ public class XsltThemeProcessor implements ThemeProcessor {
final Transformer transformer; final Transformer transformer;
try { try {
transformer = transformerFactory.newTransformer(xslFileStreamSource); transformer = transformerFactory.newTransformer(xslFileStreamSource);
transformer.setURIResolver(new CcmUriResolver(theme.getName(),
theme.getVersion(),
themeProvider));
} catch (TransformerConfigurationException ex) { } catch (TransformerConfigurationException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
final StringWriter resultWriter = new StringWriter(); final StringWriter resultWriter = new StringWriter();
final Result result = new StreamResult(resultWriter); final Result result = new StreamResult(resultWriter);
try { try {
@ -158,7 +163,7 @@ public class XsltThemeProcessor implements ThemeProcessor {
} catch (TransformerException ex) { } catch (TransformerException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
return resultWriter.toString(); return resultWriter.toString();
} }

View File

@ -641,3 +641,17 @@ ui.admin.sites.created_new_site=Create new site "{0}"
ui.admin.sites.saved_changes=Saved changes to site "{0}" ui.admin.sites.saved_changes=Saved changes to site "{0}"
ui.admin.sites.site_deleted=Site "{0}" deleted ui.admin.sites.site_deleted=Site "{0}" deleted
ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"? ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"?
ui.admin.pagemodels.name.error.empty=The name of a Page Model can't be empty.
ui.admin.pagemodels.title.error.empty=The title of a PageModel can't be empty.
ui.admin.pagemodels.application.error.empty=A PageModel must be assigned to an application
ui.admin.pagemodels.application.error.invalid=PageModel is not assigned to valid application.
ui.admin.pagemodels.details.back=Back to list of page models.
ui.admin.pagemodels.details.heading=Details of PageModel {0}
ui.admin.pagemodels.componentmodels.none=No components have been added to this PageModel.
ui.admin.pagemodels.componentmodels.cols.key.heading=Key
ui.admin.pagemodels.componentmodels.cols.type.heading=Type
ui.admin.pagemodels.componentmodels.cols.edit.heading=Edit
ui.admin.pagemodels.componentmodels.cols.delete.heading=Delete
ui.admin.pagemodels.components.edit=Edit
ui.admin.pagemodels.components.delete=Delete
ui.admin.pagemodels.details.add_component=Add Component

View File

@ -645,3 +645,17 @@ ui.admin.sites.created_new_site=Neue Site "{0}" angelegt
ui.admin.sites.saved_changes=\u00c4nderungen an Seite "{0}" gespeichert ui.admin.sites.saved_changes=\u00c4nderungen an Seite "{0}" gespeichert
ui.admin.sites.site_deleted=Site "{0}" gel\u00f6scht ui.admin.sites.site_deleted=Site "{0}" gel\u00f6scht
ui.admin.sites.site_delete.confirm=Sind Sie sicher, dass Sie die Site "{0}" l\u00f6schen wollen? ui.admin.sites.site_delete.confirm=Sind Sie sicher, dass Sie die Site "{0}" l\u00f6schen wollen?
ui.admin.pagemodels.name.error.empty=Der Name eines PageModels darf nicht leer sein.
ui.admin.pagemodels.title.error.empty=Der Titel eines PageModels darf nicht leer sein.
ui.admin.pagemodels.application.error.empty=Ein PageModel muss einer Applikation zugeordnet werden.
ui.admin.pagemodels.application.error.invalid=Das PageModel ist nicht einer g\u00fcltigen Anwendung zugeordnet.
ui.admin.pagemodels.details.back=Zur\u00fcck zur Liste der PageModels
ui.admin.pagemodels.details.heading=Details PageModel {0}
ui.admin.pagemodels.componentmodels.none=Diesem PageModel wurden noch keine Komponenten hinzugef\u00fcgt.
ui.admin.pagemodels.componentmodels.cols.key.heading=Key
ui.admin.pagemodels.componentmodels.cols.type.heading=Typ
ui.admin.pagemodels.componentmodels.cols.edit.heading=Bearbeiten
ui.admin.pagemodels.componentmodels.cols.delete.heading=Delete
ui.admin.pagemodels.components.edit=Bearbeiten
ui.admin.pagemodels.components.delete=L\u00f6schen
ui.admin.pagemodels.details.add_component=Komponente hinzuf\u00fcgen

View File

@ -638,3 +638,17 @@ ui.admin.sites.created_new_site=Create new site "{0}"
ui.admin.sites.saved_changes=Saved changes to site "{0}" ui.admin.sites.saved_changes=Saved changes to site "{0}"
ui.admin.sites.site_deleted=Site "{0}" deleted ui.admin.sites.site_deleted=Site "{0}" deleted
ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"? ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"?
ui.admin.pagemodels.name.error.empty=The name of a Page Model can't be empty.
ui.admin.pagemodels.title.error.empty=The title of a PageModel can't be empty.
ui.admin.pagemodels.application.error.empty=A PageModel must be assigned to an application
ui.admin.pagemodels.application.error.invalid=PageModel is not assigned to valid application.
ui.admin.pagemodels.details.back=Back to list of page models.
ui.admin.pagemodels.details.heading=Details of PageModel {0}
ui.admin.pagemodels.componentmodels.none=No components have been added to this PageModel.
ui.admin.pagemodels.componentmodels.cols.key.heading=Key
ui.admin.pagemodels.componentmodels.cols.type.heading=Type
ui.admin.pagemodels.componentmodels.cols.edit.heading=Edit
ui.admin.pagemodels.componentmodels.cols.delete.heading=Delete
ui.admin.pagemodels.components.edit=Edit
ui.admin.pagemodels.components.delete=Delete
ui.admin.pagemodels.details.add_component=Add Component

View File

@ -629,3 +629,17 @@ ui.admin.sites.created_new_site=Create new site "{0}"
ui.admin.sites.saved_changes=Saved changes to site "{0}" ui.admin.sites.saved_changes=Saved changes to site "{0}"
ui.admin.sites.site_deleted=Site "{0}" deleted ui.admin.sites.site_deleted=Site "{0}" deleted
ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"? ui.admin.sites.site_delete.confirm=Are you sure to delete Site "{0}"?
ui.admin.pagemodels.name.error.empty=The name of a Page Model can't be empty.
ui.admin.pagemodels.title.error.empty=The title of a PageModel can't be empty.
ui.admin.pagemodels.application.error.empty=A PageModel must be assigned to an application
ui.admin.pagemodels.application.error.invalid=PageModel is not assigned to valid application.
ui.admin.pagemodels.details.back=Back to list of page models.
ui.admin.pagemodels.details.heading=Details of PageModel {0}
ui.admin.pagemodels.componentmodels.none=No components have been added to this PageModel.
ui.admin.pagemodels.componentmodels.cols.key.heading=Key
ui.admin.pagemodels.componentmodels.cols.type.heading=Type
ui.admin.pagemodels.componentmodels.cols.edit.heading=Edit
ui.admin.pagemodels.componentmodels.cols.delete.heading=Delete
ui.admin.pagemodels.components.edit=Edit
ui.admin.pagemodels.components.delete=Delete
ui.admin.pagemodels.details.add_component=Add Component