CCM NG: Removed experimental UI using Vaadin 8. The code does not work with current Vaadin versions anymore.
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5810 8810af33-2d31-482b-a856-94f89814c4df
Former-commit-id: a231eecfe1
pull/2/head
parent
ac078b2ee5
commit
0ab99cf162
|
|
@ -194,7 +194,6 @@
|
|||
<type>jar</type>
|
||||
<includes>
|
||||
<include>assets/</include>
|
||||
<include>VAADIN/</include>
|
||||
</includes>
|
||||
</overlay>
|
||||
<overlay>
|
||||
|
|
|
|||
|
|
@ -193,7 +193,6 @@
|
|||
<type>jar</type>
|
||||
<includes>
|
||||
<include>assets/</include>
|
||||
<include>VAADIN/</include>
|
||||
</includes>
|
||||
</overlay>
|
||||
<overlay>
|
||||
|
|
|
|||
|
|
@ -67,12 +67,6 @@
|
|||
<artifactId>log4j-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Vaadin dependencies for Vaadin prototype -->
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-cdi</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<reporting>
|
||||
|
|
|
|||
|
|
@ -99,20 +99,6 @@
|
|||
<artifactId>shiro-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Vaadin dependencies for Vaadin prototype -->
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-themes</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-client-compiled</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-cdi</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
@ -259,23 +245,6 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>resources</goal>
|
||||
<goal>update-theme</goal>
|
||||
<goal>update-widgetset</goal>
|
||||
<goal>compile-theme</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
|
@ -349,7 +318,7 @@
|
|||
<linkXref>true</linkXref>
|
||||
<sourceEncoding>utf-8</sourceEncoding>
|
||||
<targetJdk>1.8</targetJdk>
|
||||
<!-- <rulesets>
|
||||
<!-- <rulesets>
|
||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||
<ruleset>/rulesets/java/braces.xml</ruleset>
|
||||
<ruleset>/rulesets/java/clone.xml</ruleset>
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.CDIUI;
|
||||
import com.vaadin.cdi.CDIViewProvider;
|
||||
import com.vaadin.cdi.URLMapping;
|
||||
import com.vaadin.navigator.Navigator;
|
||||
import com.vaadin.server.VaadinRequest;
|
||||
import com.vaadin.ui.UI;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@URLMapping("vaadin")
|
||||
@CDIUI("cms")
|
||||
public class CmsUI extends UI {
|
||||
|
||||
private static final long serialVersionUID = 1867619939266841203L;
|
||||
|
||||
@Inject
|
||||
private CDIViewProvider viewProvider;
|
||||
|
||||
@Inject
|
||||
private Subject subject;
|
||||
|
||||
@Inject
|
||||
private PermissionChecker permissionChecker;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Override
|
||||
protected void init(final VaadinRequest request) {
|
||||
|
||||
final Navigator navigator = new Navigator(this, this);
|
||||
navigator.addProvider(viewProvider);
|
||||
|
||||
// navigator.addViewChangeListener(new AuthNavListener());
|
||||
|
||||
if (subject.isAuthenticated()) {
|
||||
navigator.navigateTo(CmsView.VIEWNAME);
|
||||
} else {
|
||||
navigator.navigateTo(LoginView.VIEWNAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.CDIView;
|
||||
import com.vaadin.navigator.View;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@CDIView(value = CmsView.VIEWNAME,
|
||||
uis = {CmsUI.class})
|
||||
class CmsView extends CustomComponent implements View {
|
||||
|
||||
private static final long serialVersionUID = 8989848156887929448L;
|
||||
|
||||
public static final String VIEWNAME = "cms";
|
||||
|
||||
private final TabSheet tabSheet;
|
||||
|
||||
@Inject
|
||||
CmsView(final CmsViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
tabSheet = new TabSheet();
|
||||
|
||||
final ContentSectionsGrid sectionsGrid = new ContentSectionsGrid(controller);
|
||||
sectionsGrid.setWidth("100%");
|
||||
tabSheet.addTab(sectionsGrid, "Content Section");
|
||||
tabSheet.addTab(new PagesTab(controller), "Pages");
|
||||
tabSheet.addTab(new Label("Placeholder"), "Search");
|
||||
tabSheet.addTab(new Label("Placeholder"), "My tasks");
|
||||
|
||||
super.setCompositionRoot(tabSheet);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.librecms.pages.PageManager;
|
||||
import org.librecms.pages.PageRepository;
|
||||
import org.librecms.pages.PagesManager;
|
||||
import org.librecms.pages.PagesRepository;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class CmsViewController {
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private PagesController pagesController;
|
||||
|
||||
|
||||
@Inject
|
||||
private PermissionManager permissionManager;
|
||||
|
||||
@Inject
|
||||
private PermissionChecker permissionChecker;
|
||||
|
||||
@Inject
|
||||
private ContentSectionsGridDataProvider sectionsDataProvider;
|
||||
|
||||
protected GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
|
||||
protected PagesController getPagesController() {
|
||||
return pagesController;
|
||||
}
|
||||
|
||||
protected PermissionManager getPermissionManager() {
|
||||
return permissionManager;
|
||||
}
|
||||
|
||||
protected PermissionChecker getPermissionChecker() {
|
||||
return permissionChecker;
|
||||
}
|
||||
|
||||
protected ContentSectionsGridDataProvider getSectionsDataProvider() {
|
||||
return sectionsDataProvider;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contenttypes.AuthoringKitInfo;
|
||||
import org.librecms.contenttypes.AuthoringStepInfo;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
import org.librecms.contenttypes.ContentTypesManager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ContentItemEditor<T extends ContentItem> extends Window {
|
||||
|
||||
private static final long serialVersionUID = 3341827053652019616L;
|
||||
|
||||
private List<Component> authoringsSteps;
|
||||
|
||||
public ContentItemEditor(final ContentSectionViewController controller,
|
||||
final T item) {
|
||||
|
||||
super();
|
||||
|
||||
final ContentTypesManager typesManager = controller
|
||||
.getContentTypesManager();
|
||||
final ContentTypeInfo typeInfo = typesManager
|
||||
.getContentTypeInfo(item.getContentType());
|
||||
|
||||
final AuthoringKitInfo authoringKitInfo = typeInfo.getAuthoringKit();
|
||||
final List<AuthoringStepInfo> authoringsStepInfos = authoringKitInfo
|
||||
.getAuthoringSteps();
|
||||
|
||||
final VerticalLayout sidebar = new VerticalLayout();
|
||||
final VerticalLayout mainArea = new VerticalLayout();
|
||||
for (final AuthoringStepInfo stepInfo : authoringsStepInfos) {
|
||||
|
||||
final String componentClassName;
|
||||
if (stepInfo.getComponent().getName()
|
||||
.startsWith("com.arsdigita.cms")) {
|
||||
componentClassName = stepInfo
|
||||
.getComponent()
|
||||
.getName()
|
||||
.replace("com.arsdigita.cms", "org.librecms");
|
||||
} else if (stepInfo.getComponent().getName().startsWith(
|
||||
"com.arsdigita")) {
|
||||
componentClassName = stepInfo
|
||||
.getComponent()
|
||||
.getName()
|
||||
.replace("com.arsdigita", "org.libreccm");
|
||||
} else {
|
||||
componentClassName = stepInfo.getComponent().getName();
|
||||
}
|
||||
|
||||
final Component authoringStep = createAuthoringStep(
|
||||
controller, item, componentClassName);
|
||||
final ResourceBundle resourceBundle = ResourceBundle
|
||||
.getBundle(stepInfo.getLabelBundle(),
|
||||
controller
|
||||
.getGlobalizationHelper()
|
||||
.getNegotiatedLocale());
|
||||
final Button button = new Button(resourceBundle
|
||||
.getString(stepInfo.getLabelKey()));
|
||||
button.addStyleName(ValoTheme.BUTTON_LINK);
|
||||
button.addClickListener(event-> authoringStep.setVisible(true));
|
||||
authoringStep.setVisible(false);
|
||||
sidebar.addComponent(button);
|
||||
mainArea.addComponent(authoringStep);
|
||||
authoringsSteps.add(authoringStep);
|
||||
}
|
||||
|
||||
authoringsSteps.get(0).setVisible(true);
|
||||
}
|
||||
|
||||
private Component createAuthoringStep(
|
||||
final ContentSectionViewController controller,
|
||||
final T item,
|
||||
final String componentClassName) {
|
||||
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Class<Component> stepClass = (Class<Component>) Class
|
||||
.forName(componentClassName);
|
||||
|
||||
return stepClass
|
||||
.getDeclaredConstructor(ContentSectionViewController.class,
|
||||
item.getClass())
|
||||
.newInstance(controller, item);
|
||||
} catch (ClassNotFoundException
|
||||
| NoSuchMethodException
|
||||
| InstantiationException
|
||||
| IllegalAccessException
|
||||
| InvocationTargetException ex) {
|
||||
|
||||
final Label label = new Label(String
|
||||
.format("AuthoringStep \"%s\" not available",
|
||||
componentClassName));
|
||||
label.addStyleName(ValoTheme.LABEL_FAILURE);
|
||||
return new VerticalLayout(label);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.CDIView;
|
||||
import com.vaadin.navigator.View;
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@CDIView(value = ContentSectionView.VIEWNAME,
|
||||
uis = {CmsUI.class})
|
||||
class ContentSectionView extends CustomComponent implements View {
|
||||
|
||||
private static final long serialVersionUID = 602851260519364741L;
|
||||
|
||||
public static final String VIEWNAME = "ContentSection";
|
||||
|
||||
private static final String TAB_DOCUMENTS = "tab_documents";
|
||||
private static final String TAB_SEARCH = "tab_search";
|
||||
private static final String TAB_MEDIA = "tab_media";
|
||||
private static final String TAB_ROLES = "tab_roles";
|
||||
private static final String TAB_WORKFLOWS = "tab_workflows";
|
||||
private static final String TAB_LIFECYCLES = "tab_lifecycles";
|
||||
private static final String TAB_DOCUMENT_TYPES = "tab_document_types";
|
||||
|
||||
private final ContentSectionViewController controller;
|
||||
|
||||
private ContentSection selectedSection;
|
||||
|
||||
private final TabSheet tabSheet;
|
||||
private final Panel noSectionPanel;
|
||||
|
||||
private final FolderBrowser folderBrowser;
|
||||
|
||||
@Inject
|
||||
ContentSectionView(final ContentSectionViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
folderBrowser = new FolderBrowser(controller);
|
||||
final VerticalLayout folderBrowserLayout = new VerticalLayout();
|
||||
folderBrowserLayout.setHeight("100%");
|
||||
folderBrowserLayout.addComponentsAndExpand(folderBrowser);
|
||||
|
||||
tabSheet = new TabSheet();
|
||||
tabSheet
|
||||
.addTab(folderBrowser, "Documents")
|
||||
.setId(TAB_DOCUMENTS);
|
||||
tabSheet
|
||||
.addTab(new Label("Search placeholder"), "Search")
|
||||
.setId(TAB_SEARCH);
|
||||
tabSheet
|
||||
.addTab(new Label("Media & Records placeholder"), "Media & Records")
|
||||
.setId(TAB_MEDIA);
|
||||
tabSheet
|
||||
.addTab(new Label("Roles placeholder"), "Roles")
|
||||
.setId(TAB_ROLES);
|
||||
tabSheet
|
||||
.addTab(new Label("Workflows Placeholder"), "Workflows")
|
||||
.setId(TAB_WORKFLOWS);
|
||||
tabSheet
|
||||
.addTab(new Label("Lifecycles placeholder"), "Lifecycles")
|
||||
.setId(TAB_LIFECYCLES);
|
||||
tabSheet
|
||||
.addTab(new Label("Document types placeholder"), "Documents types")
|
||||
.setId(TAB_DOCUMENT_TYPES);
|
||||
|
||||
tabSheet.addSelectedTabChangeListener(event -> {
|
||||
|
||||
final Component selectedTab = event.getTabSheet().getSelectedTab();
|
||||
|
||||
if (TAB_DOCUMENTS.equals(selectedTab.getId())) {
|
||||
|
||||
final FolderBrowser browser = (FolderBrowser) selectedTab;
|
||||
|
||||
browser
|
||||
.getFolderTree()
|
||||
.expand(controller
|
||||
.getContentSectionViewState()
|
||||
.getSelectedContentSection()
|
||||
.getRootDocumentsFolder());
|
||||
}
|
||||
});
|
||||
|
||||
tabSheet.setHeight("100%");
|
||||
|
||||
noSectionPanel = new Panel();
|
||||
noSectionPanel.setVisible(false);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout();
|
||||
layout.addComponentsAndExpand(tabSheet, noSectionPanel);
|
||||
layout.setHeight("100%");
|
||||
layout.addStyleName("content-section-view-layout");
|
||||
|
||||
super.setCompositionRoot(layout);
|
||||
super.setHeight("100%");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter(ViewChangeListener.ViewChangeEvent event) {
|
||||
|
||||
final String parameters = event.getParameters();
|
||||
|
||||
if (parameters == null || parameters.trim().isEmpty()) {
|
||||
tabSheet.setVisible(false);
|
||||
noSectionPanel.setCaption("No content section selected");
|
||||
noSectionPanel.setContent(new Label("No content section selected"));
|
||||
noSectionPanel.setVisible(true);
|
||||
} else {
|
||||
final ContentSectionRepository sectionRepo = controller
|
||||
.getSectionRepository();
|
||||
|
||||
final Optional<ContentSection> contentSection = sectionRepo
|
||||
.findByLabel(parameters);
|
||||
|
||||
if (contentSection.isPresent()) {
|
||||
selectedSection = contentSection.get();
|
||||
controller
|
||||
.getContentSectionViewState()
|
||||
.setSelectedContentSection(selectedSection);
|
||||
|
||||
folderBrowser
|
||||
.getFolderTree()
|
||||
.expand(controller
|
||||
.getContentSectionViewState()
|
||||
.getSelectedContentSection()
|
||||
.getRootDocumentsFolder());
|
||||
} else {
|
||||
tabSheet.setVisible(false);
|
||||
noSectionPanel.setCaption(String
|
||||
.format("No content section \"%s\"", parameters));
|
||||
noSectionPanel.setContent(new Label(String
|
||||
.format("No content section with label \"%s\" found.",
|
||||
parameters)));
|
||||
noSectionPanel.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.ui.LocalizedStringWidgetController;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
import org.librecms.contentsection.FolderRepository;
|
||||
import org.librecms.contenttypes.ContentTypesManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class ContentSectionViewController {
|
||||
|
||||
@Inject
|
||||
private FolderBrowserDataProvider browseDocumentsDataProvider;
|
||||
|
||||
@Inject
|
||||
private FolderBrowserFolderTreeDataProvider folderTreeDataProvider;
|
||||
|
||||
@Inject
|
||||
private ContentTypesManager contentTypesManager;
|
||||
|
||||
@Inject
|
||||
private FolderRepository folderRepository;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private LocalizedStringWidgetController localizedStringWidgetController;
|
||||
|
||||
@Inject
|
||||
private PermissionChecker permissionChecker;
|
||||
|
||||
@Inject
|
||||
private ContentSectionRepository sectionRepository;
|
||||
|
||||
@Inject
|
||||
private ContentSectionViewState contentSectionViewState;
|
||||
|
||||
protected FolderBrowserDataProvider getBrowseDocumentsDataProvider() {
|
||||
return browseDocumentsDataProvider;
|
||||
}
|
||||
|
||||
public FolderBrowserFolderTreeDataProvider getFolderTreeDataProvider() {
|
||||
return folderTreeDataProvider;
|
||||
}
|
||||
|
||||
public ContentTypesManager getContentTypesManager() {
|
||||
return contentTypesManager;
|
||||
}
|
||||
|
||||
public FolderRepository getFolderRepository() {
|
||||
return folderRepository;
|
||||
}
|
||||
|
||||
public GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
public LocalizedStringWidgetController getLocalizedStringWidgetController() {
|
||||
return localizedStringWidgetController;
|
||||
}
|
||||
|
||||
public PermissionChecker getPermissionChecker() {
|
||||
return permissionChecker;
|
||||
}
|
||||
|
||||
public ContentSectionRepository getSectionRepository() {
|
||||
return sectionRepository;
|
||||
}
|
||||
|
||||
protected ContentSectionViewState getContentSectionViewState() {
|
||||
return contentSectionViewState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class ContentSectionViewState {
|
||||
|
||||
private ContentSection selectedContentSection;
|
||||
|
||||
protected ContentSection getSelectedContentSection() {
|
||||
return selectedContentSection;
|
||||
}
|
||||
|
||||
protected void setSelectedContentSection(
|
||||
final ContentSection selectedContentSection) {
|
||||
this.selectedContentSection = selectedContentSection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.privileges.AdminPrivileges;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class ContentSectionsGrid extends Grid<ContentSection> {
|
||||
|
||||
private static final long serialVersionUID = -2840544148539285341L;
|
||||
|
||||
private static final String COL_LABEL = "label";
|
||||
private static final String COL_EDIT = "edit";
|
||||
private static final String COL_DELETE = "delete";
|
||||
|
||||
private final CmsViewController controller;
|
||||
|
||||
public ContentSectionsGrid(final CmsViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addComponentColumn(this::buildSectionLink)
|
||||
.setId(COL_LABEL)
|
||||
.setCaption("Content Section");
|
||||
addComponentColumn(this::buildEditButton)
|
||||
.setId(COL_EDIT)
|
||||
.setCaption("Edit");
|
||||
addComponentColumn(this::buildDeleteButton)
|
||||
.setId(COL_DELETE)
|
||||
.setCaption("Delete");
|
||||
|
||||
setSelectionMode(SelectionMode.NONE);
|
||||
|
||||
setDataProvider(controller.getSectionsDataProvider());
|
||||
|
||||
if (controller.getPermissionChecker().isPermitted("admin")) {
|
||||
final HeaderRow actionsRow = prependHeaderRow();
|
||||
final HeaderCell actionsCell = actionsRow.join(COL_LABEL,
|
||||
COL_EDIT,
|
||||
COL_DELETE);
|
||||
|
||||
final Button createButton = new Button("Create new content section",
|
||||
VaadinIcons.PLUS_CIRCLE_O);
|
||||
createButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
createButton.addClickListener(event -> {
|
||||
});
|
||||
|
||||
final HorizontalLayout actionsLayout = new HorizontalLayout(
|
||||
createButton);
|
||||
actionsCell.setComponent(actionsLayout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Component buildSectionLink(final ContentSection section) {
|
||||
|
||||
final PermissionChecker permissionChecker = controller
|
||||
.getPermissionChecker();
|
||||
|
||||
if (canAccessSection(section)) {
|
||||
final Button button = new Button();
|
||||
button.setCaption(section.getLabel());
|
||||
button.setStyleName(ValoTheme.BUTTON_LINK);
|
||||
button.addClickListener(event -> {
|
||||
getUI()
|
||||
.getNavigator()
|
||||
.navigateTo(String.format("%s/%s",
|
||||
ContentSectionView.VIEWNAME,
|
||||
section.getLabel()));
|
||||
});
|
||||
return button;
|
||||
} else {
|
||||
return new Label(section.getLabel());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canAccessSection(final ContentSection section) {
|
||||
final List<String> adminPrivileges = controller
|
||||
.getPermissionManager()
|
||||
.listDefiniedPrivileges(AdminPrivileges.class);
|
||||
final List<String> itemPrivileges = controller
|
||||
.getPermissionManager()
|
||||
.listDefiniedPrivileges(ItemPrivileges.class);
|
||||
|
||||
for (final String privilege : adminPrivileges) {
|
||||
if (controller.getPermissionChecker().isPermitted(privilege)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (final String privilege : itemPrivileges) {
|
||||
if (controller.getPermissionChecker().isPermitted(privilege)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return controller.getPermissionChecker().isPermitted("admin");
|
||||
}
|
||||
|
||||
private Component buildEditButton(final ContentSection section) {
|
||||
|
||||
if (controller.getPermissionChecker().isPermitted("admin")) {
|
||||
final Button button = new Button("Edit", VaadinIcons.EDIT);
|
||||
button.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
button.addClickListener(event -> {
|
||||
});
|
||||
return button;
|
||||
} else {
|
||||
return new Label("");
|
||||
}
|
||||
}
|
||||
|
||||
private Component buildDeleteButton(final ContentSection section) {
|
||||
|
||||
if (controller.getPermissionChecker().isPermitted("admin")) {
|
||||
final Button button = new Button("Delete", VaadinIcons.DEL);
|
||||
button.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
button.addStyleName(ValoTheme.BUTTON_DANGER);
|
||||
button.addClickListener(event -> {
|
||||
});
|
||||
return button;
|
||||
} else {
|
||||
return new Label("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class ContentSectionsGridDataProvider
|
||||
extends AbstractBackEndDataProvider<ContentSection, String> {
|
||||
|
||||
private static final long serialVersionUID = 2173898409635046482L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private ContentSectionRepository sectionRepo;
|
||||
|
||||
@Override
|
||||
protected Stream<ContentSection> fetchFromBackEnd(
|
||||
final Query<ContentSection, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<ContentSection> criteriaQuery = builder
|
||||
.createQuery(ContentSection.class);
|
||||
final Root<ContentSection> from = criteriaQuery
|
||||
.from(ContentSection.class);
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<ContentSection, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<ContentSection> from = criteriaQuery
|
||||
.from(ContentSection.class);
|
||||
|
||||
criteriaQuery.select(builder.count(from));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.HorizontalSplitPanel;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.Tree;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.renderers.DateRenderer;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FolderBrowser extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = -7241214812224026430L;
|
||||
|
||||
private static final String COL_DOCUMENT_CREATED = "created";
|
||||
private static final String COL_DOCUMENT_LAST_MODIFIED = "lastmodified";
|
||||
private static final String COL_DOCUMENT_NAME = "name";
|
||||
private static final String COL_DOCUMENT_TITLE = "title";
|
||||
private static final String COL_DOCUMENT_TYPE = "ttype";
|
||||
|
||||
private final ContentSectionViewController controller;
|
||||
|
||||
private final Tree<Folder> folderTree;
|
||||
private final Grid<FolderBrowserItem> documentsGrid;
|
||||
|
||||
private final Button renameCurrentFolderButton;
|
||||
|
||||
private final FolderBrowserDataProvider documentsDataProvider;
|
||||
private final FolderBrowserFolderTreeDataProvider folderTreeDataProvider;
|
||||
|
||||
public FolderBrowser(final ContentSectionViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
folderTreeDataProvider = controller.getFolderTreeDataProvider();
|
||||
folderTree = new Tree<>(folderTreeDataProvider);
|
||||
folderTree.setItemCaptionGenerator(folder -> {
|
||||
return controller
|
||||
.getGlobalizationHelper()
|
||||
.getValueFromLocalizedString(folder.getTitle());
|
||||
});
|
||||
|
||||
documentsGrid = new Grid<>();
|
||||
documentsGrid
|
||||
.addComponentColumn(item -> buildFolderItemLink(item))
|
||||
.setCaption("Name")
|
||||
.setId(COL_DOCUMENT_NAME);
|
||||
documentsGrid
|
||||
.addColumn(FolderBrowserItem::getTitle)
|
||||
.setCaption("Title")
|
||||
.setId(COL_DOCUMENT_TITLE);
|
||||
documentsGrid
|
||||
.addColumn(FolderBrowserItem::getType)
|
||||
.setCaption("Type")
|
||||
.setId(COL_DOCUMENT_TYPE);
|
||||
documentsGrid
|
||||
.addColumn(FolderBrowserItem::getCreationDate,
|
||||
new DateRenderer("%tF"))
|
||||
.setCaption("Created")
|
||||
.setId(COL_DOCUMENT_CREATED);
|
||||
documentsGrid
|
||||
.addColumn(FolderBrowserItem::getLastModified,
|
||||
new DateRenderer("%tF"))
|
||||
.setCaption("Last modified")
|
||||
.setId(COL_DOCUMENT_LAST_MODIFIED);
|
||||
documentsDataProvider = controller.getBrowseDocumentsDataProvider();
|
||||
documentsGrid.setDataProvider(documentsDataProvider);
|
||||
documentsGrid.setSelectionMode(Grid.SelectionMode.MULTI);
|
||||
documentsGrid.setWidth("100%");
|
||||
documentsGrid.setHeight("100%");
|
||||
|
||||
final Button createSubFolderButton = new Button("New subfolder",
|
||||
VaadinIcons.PLUS_CIRCLE_O);
|
||||
createSubFolderButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
renameCurrentFolderButton = new Button("Rename current folder",
|
||||
VaadinIcons.EDIT);
|
||||
renameCurrentFolderButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
renameCurrentFolderButton.setEnabled(false);
|
||||
renameCurrentFolderButton.setVisible(false);
|
||||
final HeaderRow headerRow = documentsGrid.prependHeaderRow();
|
||||
final HeaderCell actionsCell = headerRow.join(COL_DOCUMENT_NAME,
|
||||
COL_DOCUMENT_TITLE,
|
||||
COL_DOCUMENT_TYPE,
|
||||
COL_DOCUMENT_CREATED,
|
||||
COL_DOCUMENT_LAST_MODIFIED);
|
||||
actionsCell.setComponent(new HorizontalLayout(createSubFolderButton,
|
||||
renameCurrentFolderButton));
|
||||
|
||||
folderTree.addItemClickListener(event -> {
|
||||
// documentsDataProvider.setCurrentFolder(event.getItem());
|
||||
// documentsDataProvider.refreshAll();
|
||||
setCurrentFolder(event.getItem());
|
||||
});
|
||||
folderTree.setItemCollapseAllowedProvider(folder -> {
|
||||
return folder.getParentCategory() != null;
|
||||
});
|
||||
|
||||
// final Button root = new Button("/ ");
|
||||
// root.addStyleName(ValoTheme.BUTTON_LINK);
|
||||
// root.addClickListener(event -> {
|
||||
// folderTree.getSelectionModel().deselectAll();
|
||||
// documentsDataProvider.setCurrentFolder(null);
|
||||
// documentsDataProvider.refreshAll();
|
||||
// });
|
||||
// final VerticalLayout folders = new VerticalLayout(root, folderTree);
|
||||
final VerticalLayout folderTreeLayout = new VerticalLayout(folderTree);
|
||||
|
||||
final VerticalLayout documentsGridLayout = new VerticalLayout();
|
||||
documentsGridLayout.addComponentsAndExpand(documentsGrid);
|
||||
|
||||
final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(
|
||||
folderTreeLayout, documentsGridLayout);
|
||||
splitPanel.setSplitPosition(17.5f, Unit.PERCENTAGE);
|
||||
splitPanel.setHeight("100%");
|
||||
final VerticalLayout layout = new VerticalLayout();
|
||||
layout.addComponentsAndExpand(splitPanel);
|
||||
super.setCompositionRoot(layout);
|
||||
}
|
||||
|
||||
private Component buildFolderItemLink(final FolderBrowserItem item) {
|
||||
|
||||
final Button itemLink = new Button();
|
||||
itemLink.setCaption(item.getName());
|
||||
itemLink.setStyleName(ValoTheme.BUTTON_LINK);
|
||||
itemLink.addClickListener(event -> folderBrowserItemClicked(event,
|
||||
item));
|
||||
if (item.isFolder()) {
|
||||
itemLink.setIcon(VaadinIcons.FOLDER);
|
||||
}
|
||||
|
||||
return itemLink;
|
||||
}
|
||||
|
||||
private void folderBrowserItemClicked(final Button.ClickEvent event,
|
||||
final FolderBrowserItem item) {
|
||||
|
||||
if (item.isFolder()) {
|
||||
final Folder folder = controller
|
||||
.getFolderRepository()
|
||||
.findById(item.getItemId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"No Folder with ID %d in the database.",
|
||||
item.getItemId())));
|
||||
// folderTree.expand(folder);
|
||||
// documentsDataProvider.setCurrentFolder(folder);
|
||||
// documentsDataProvider.refreshAll();
|
||||
setCurrentFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCurrentFolder(final Folder folder) {
|
||||
folderTree.expand(folder);
|
||||
documentsDataProvider.setCurrentFolder(folder);
|
||||
documentsDataProvider.refreshAll();
|
||||
|
||||
renameCurrentFolderButton.setEnabled(folder.getParentCategory() != null);
|
||||
renameCurrentFolderButton.setVisible(folder.getParentCategory() != null);
|
||||
}
|
||||
|
||||
public Tree<Folder> getFolderTree() {
|
||||
return folderTree;
|
||||
}
|
||||
|
||||
public Grid<FolderBrowserItem> getDocumentsGrid() {
|
||||
return documentsGrid;
|
||||
}
|
||||
|
||||
private class FolderDialog extends Window {
|
||||
|
||||
private static final long serialVersionUID = -6767403288966354533L;
|
||||
|
||||
private final TextField nameField;
|
||||
private final TextField titleField;
|
||||
private final Button submitButton;
|
||||
|
||||
private Folder currentFolder;
|
||||
|
||||
public FolderDialog() {
|
||||
super();
|
||||
|
||||
nameField = new TextField("Name");
|
||||
nameField.setDescription("The name (URL-Fragment) of the folder.");
|
||||
nameField.setRequiredIndicatorVisible(true);
|
||||
nameField.setMaxLength(256);
|
||||
|
||||
titleField = new TextField("Title");
|
||||
titleField.setDescription("The title of the folder.");
|
||||
titleField.setRequiredIndicatorVisible(true);
|
||||
titleField.setMaxLength(256);
|
||||
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.addClickListener(event -> close());
|
||||
|
||||
submitButton = new Button("Submit");
|
||||
submitButton.addClickListener(event -> save());
|
||||
|
||||
final FormLayout layout = new FormLayout(nameField,
|
||||
titleField,
|
||||
cancelButton,
|
||||
submitButton);
|
||||
|
||||
super.setContent(layout);
|
||||
}
|
||||
|
||||
public FolderDialog(final Folder folder) {
|
||||
this();
|
||||
|
||||
currentFolder = folder;
|
||||
nameField.setValue(currentFolder.getName());
|
||||
|
||||
}
|
||||
|
||||
private void save() {
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,498 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.categorization.Categorization;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
import org.librecms.contenttypes.ContentTypesManager;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.Subquery;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class FolderBrowserDataProvider
|
||||
extends AbstractBackEndDataProvider<FolderBrowserItem, String> {
|
||||
|
||||
private static final long serialVersionUID = 7693820518000376630L;
|
||||
|
||||
@Inject
|
||||
private ContentSectionViewState contentSectionViewState;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private ContentTypesManager typesManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
private Folder currentFolder;
|
||||
|
||||
|
||||
protected Folder getCurrentFolder() {
|
||||
return currentFolder;
|
||||
}
|
||||
|
||||
protected void setCurrentFolder(final Folder currentFolder) {
|
||||
this.currentFolder = currentFolder;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
protected Stream<FolderBrowserItem> fetchFromBackEnd(
|
||||
final Query<FolderBrowserItem, String> query) {
|
||||
|
||||
final Folder folder;
|
||||
if (currentFolder == null) {
|
||||
folder = contentSectionViewState
|
||||
.getSelectedContentSection()
|
||||
.getRootDocumentsFolder();
|
||||
} else {
|
||||
folder = currentFolder;
|
||||
}
|
||||
|
||||
final CriteriaBuilder criteriaBuilder = entityManager
|
||||
.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<CcmObject> criteriaQuery = criteriaBuilder
|
||||
.createQuery(CcmObject.class);
|
||||
|
||||
final Subquery<Folder> folderQuery = criteriaQuery
|
||||
.subquery(Folder.class);
|
||||
final Root<Folder> fromFolder = folderQuery.from(Folder.class);
|
||||
folderQuery.select(fromFolder);
|
||||
if (query.getFilter().isPresent()) {
|
||||
final String filter = query.getFilter().get();
|
||||
folderQuery.where(criteriaBuilder
|
||||
.and(
|
||||
criteriaBuilder.equal(fromFolder.get("parentCategory"),
|
||||
folder),
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.like(fromFolder.get("name"),
|
||||
String.format("%s%%", filter)),
|
||||
criteriaBuilder.like(fromFolder.get("displayName"),
|
||||
String.format("%s%%", filter)))));
|
||||
} else {
|
||||
folderQuery
|
||||
.where(criteriaBuilder.equal(fromFolder.get("parentCategory"),
|
||||
folder));
|
||||
}
|
||||
|
||||
final Subquery<ContentItem> itemQuery = criteriaQuery
|
||||
.subquery(ContentItem.class);
|
||||
final Root<ContentItem> fromItem = itemQuery.from(ContentItem.class);
|
||||
final Join<ContentItem, Categorization> joinCat = fromItem
|
||||
.join("categories");
|
||||
itemQuery.select(fromItem);
|
||||
if (query.getFilter().isPresent()) {
|
||||
final String filter = query.getFilter().get();
|
||||
itemQuery
|
||||
.where(criteriaBuilder.and(
|
||||
criteriaBuilder.equal(joinCat.get("category"), folder),
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.like(fromItem.get("displayName"),
|
||||
String.format("%s%%", filter)),
|
||||
criteriaBuilder.like(fromItem.get("name"),
|
||||
String.format("%s%%", filter))
|
||||
)
|
||||
));
|
||||
} else {
|
||||
itemQuery
|
||||
.where(criteriaBuilder.equal(joinCat.get("category"), folder));
|
||||
}
|
||||
|
||||
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
|
||||
criteriaQuery.select(from);
|
||||
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.in(from).value(folderQuery),
|
||||
criteriaBuilder.in(from).value(itemQuery)
|
||||
));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(this::buildRow);
|
||||
}
|
||||
|
||||
private FolderBrowserItem buildRow(final CcmObject object) {
|
||||
|
||||
final FolderBrowserItem row = new FolderBrowserItem();
|
||||
if (object instanceof Folder) {
|
||||
|
||||
final Folder folder = (Folder) object;
|
||||
row.setFolder(true);
|
||||
row.setItemId(folder.getObjectId());
|
||||
row.setName(folder.getName());
|
||||
row.setTitle(globalizationHelper
|
||||
.getValueFromLocalizedString(folder.getTitle()));
|
||||
} else if (object instanceof ContentItem) {
|
||||
|
||||
final ContentItem item = (ContentItem) object;
|
||||
row.setCreationDate(((ContentItem) object).getCreationDate());
|
||||
row.setFolder(false);
|
||||
row.setItemId(item.getObjectId());
|
||||
row.setLastModified(item.getLastModified());
|
||||
row.setName(globalizationHelper
|
||||
.getValueFromLocalizedString(item.getName()));
|
||||
row.setTitle(globalizationHelper
|
||||
.getValueFromLocalizedString(item.getTitle()));
|
||||
|
||||
final ContentTypeInfo typeInfo = typesManager
|
||||
.getContentTypeInfo(item.getClass());
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(typeInfo.getLabelBundle());
|
||||
row.setType(textsUtil.getText(typeInfo.getLabelKey()));
|
||||
} else {
|
||||
|
||||
row.setFolder(false);
|
||||
row.setItemId(object.getObjectId());
|
||||
row.setName(object.getDisplayName());
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
protected int sizeInBackEnd(
|
||||
final Query<FolderBrowserItem, String> query) {
|
||||
|
||||
final Folder folder;
|
||||
if (currentFolder == null) {
|
||||
folder = contentSectionViewState
|
||||
.getSelectedContentSection()
|
||||
.getRootDocumentsFolder();
|
||||
} else {
|
||||
folder = currentFolder;
|
||||
}
|
||||
|
||||
final CriteriaBuilder criteriaBuilder = entityManager
|
||||
.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<Long> criteriaQuery = criteriaBuilder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Subquery<Folder> folderQuery = criteriaQuery
|
||||
.subquery(Folder.class);
|
||||
final Root<Folder> fromFolder = folderQuery.from(Folder.class);
|
||||
folderQuery.select(fromFolder);
|
||||
if (query.getFilter().isPresent()) {
|
||||
final String filter = query.getFilter().get();
|
||||
folderQuery.where(criteriaBuilder
|
||||
.and(
|
||||
criteriaBuilder.equal(fromFolder.get("parentCategory"),
|
||||
folder),
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.like(fromFolder.get("name"),
|
||||
String.format("%s%%", filter)),
|
||||
criteriaBuilder.like(fromFolder.get("displayName"),
|
||||
String.format("%s%%", filter)))));
|
||||
} else {
|
||||
folderQuery
|
||||
.where(criteriaBuilder.equal(fromFolder.get("parentCategory"),
|
||||
folder));
|
||||
}
|
||||
|
||||
final Subquery<ContentItem> itemQuery = criteriaQuery
|
||||
.subquery(ContentItem.class);
|
||||
final Root<ContentItem> fromItem = itemQuery.from(ContentItem.class);
|
||||
final Join<ContentItem, Categorization> joinCat = fromItem
|
||||
.join("categories");
|
||||
itemQuery.select(fromItem);
|
||||
if (query.getFilter().isPresent()) {
|
||||
final String filter = query.getFilter().get();
|
||||
itemQuery
|
||||
.where(criteriaBuilder.and(
|
||||
criteriaBuilder.equal(joinCat.get("category"), folder),
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.like(fromItem.get("displayName"),
|
||||
String.format("%s%%", filter)),
|
||||
criteriaBuilder.like(fromItem.get("name"),
|
||||
String.format("%s%%", filter))
|
||||
)
|
||||
));
|
||||
} else {
|
||||
itemQuery
|
||||
.where(criteriaBuilder.equal(joinCat.get("category"), folder));
|
||||
}
|
||||
|
||||
final Root<CcmObject> from = criteriaQuery.from(CcmObject.class);
|
||||
criteriaQuery.select(criteriaBuilder.count(from));
|
||||
|
||||
criteriaQuery.where(
|
||||
criteriaBuilder.or(
|
||||
criteriaBuilder.in(from).value(folderQuery),
|
||||
criteriaBuilder.in(from).value(itemQuery)
|
||||
));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected Stream<BrowseDocumentsItem> fetchFromBackEnd(
|
||||
// final Query<BrowseDocumentsItem, String> query) {
|
||||
//
|
||||
// final int subFoldersCount = countSubFolder(currentFolder,
|
||||
// query.getFilter());
|
||||
// final int itemsCount = countItems(currentFolder, query.getFilter());
|
||||
//
|
||||
// final int limit = query.getLimit();
|
||||
// final int offset = query.getOffset();
|
||||
//
|
||||
// final int subFoldersLimit;
|
||||
// final int subFoldersOffset;
|
||||
// final int itemsLimit;
|
||||
// final int itemsOffset;
|
||||
// if (subFoldersCount > (limit + offset)) {
|
||||
//
|
||||
// subFoldersLimit = limit;
|
||||
//
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// final List<Folder> subFolders = fetchSubFolders(currentFolder,
|
||||
// query.getFilter(),
|
||||
// query.getLimit(),
|
||||
// query.getOffset());
|
||||
// final List<ContentItem> items = fetchItems(currentFolder,
|
||||
// query.getFilter());
|
||||
//
|
||||
// final List<BrowseDocumentsItem> subFolderItems = subFolders
|
||||
// .stream()
|
||||
// .map(this::createBrowseDocumentsItem)
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// final List<BrowseDocumentsItem> itemList = items
|
||||
// .stream()
|
||||
// .map(this::createBrowseDocumentsItem)
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// final List<BrowseDocumentsItem> rows = new ArrayList<>();
|
||||
// rows.addAll(subFolderItems);
|
||||
// rows.addAll(itemList);
|
||||
//
|
||||
// return rows.stream();
|
||||
// }
|
||||
//
|
||||
// private List<Folder> fetchSubFolders(final Folder folder,
|
||||
// final Optional<String> filter,
|
||||
// final int limit,
|
||||
// final int offset) {
|
||||
//
|
||||
// final CriteriaBuilder builder = entityManager
|
||||
// .getCriteriaBuilder();
|
||||
// final CriteriaQuery<Folder> query = builder.createQuery(Folder.class);
|
||||
// final Root<Folder> from = query.from(Folder.class);
|
||||
//
|
||||
// if (filter.isPresent()) {
|
||||
// query.where(builder
|
||||
// .and(builder.equal(from.get("parentCategory"), folder),
|
||||
// builder.or(
|
||||
// builder.like(builder.lower(from.get("name")),
|
||||
// String.format("%s%%", filter.get())),
|
||||
// builder.like(builder.lower(from.get("displayName")),
|
||||
// String.format("%s%%", filter.get())))));
|
||||
// } else {
|
||||
// query.where(builder.equal(from.get("parentCategory"), folder));
|
||||
// }
|
||||
//
|
||||
// query.orderBy(builder.asc(from.get("name")),
|
||||
// builder.asc(from.get("displayName")));
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(query)
|
||||
// .setMaxResults(limit)
|
||||
// .setFirstResult(offset)
|
||||
// .getResultList();
|
||||
// }
|
||||
//
|
||||
// private List<ContentItem> fetchItems(final Folder folder,
|
||||
// final Optional<String> filter) {
|
||||
//
|
||||
// final CriteriaBuilder builder = entityManager
|
||||
// .getCriteriaBuilder();
|
||||
// final CriteriaQuery<ContentItem> query = builder
|
||||
// .createQuery(ContentItem.class);
|
||||
// final Root<ContentItem> from = query.from(ContentItem.class);
|
||||
// final Join<ContentItem, Categorization> join = from.join("categories");
|
||||
//
|
||||
// if (filter.isPresent()) {
|
||||
// query.where(builder
|
||||
// .and(builder.equal(join.get("category"), folder),
|
||||
// builder.or(
|
||||
// builder.like(builder.lower(from.get("name")),
|
||||
// String.format("%s%%", filter.get())),
|
||||
// builder.like(builder.lower(from.get("displayName")),
|
||||
// String.format("%s%%", filter.get())))));
|
||||
//
|
||||
// } else {
|
||||
// query.where(builder.equal(join.get("category"), folder));
|
||||
// }
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(query)
|
||||
// .getResultList();
|
||||
// }
|
||||
//
|
||||
// private FolderBrowserItem createBrowseDocumentsItem(
|
||||
// final Folder fromFolder) {
|
||||
//
|
||||
// final FolderBrowserItem item = new FolderBrowserItem();
|
||||
// item.setItemId(fromFolder.getObjectId());
|
||||
// item.setName(fromFolder.getName());
|
||||
// item.setTitle(fromFolder
|
||||
// .getTitle()
|
||||
// .getValue(controller.getGlobalizationHelper().getNegotiatedLocale()));
|
||||
// item.setFolder(true);
|
||||
//
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// private FolderBrowserItem createBrowseDocumentsItem(
|
||||
// final ContentItem fromItem) {
|
||||
//
|
||||
// final FolderBrowserItem item = new FolderBrowserItem();
|
||||
// item.setCreationDate(fromItem.getCreationDate());
|
||||
// item.setFolder(false);
|
||||
// item.setItemId(fromItem.getObjectId());
|
||||
// item.setLastChanged(fromItem.getLastModified());
|
||||
// item.setName(item.getName());
|
||||
// item.setTitle(fromItem
|
||||
// .getTitle()
|
||||
// .getValue(controller.getGlobalizationHelper().getNegotiatedLocale()));
|
||||
//
|
||||
// final ContentTypesManager typesManager = controller
|
||||
// .getContentTypesManager();
|
||||
// final ContentTypeInfo typeInfo = typesManager
|
||||
// .getContentTypeInfo(fromItem.getContentType());
|
||||
// final LocalizedTextsUtil textsUtil = controller
|
||||
// .getGlobalizationHelper()
|
||||
// .getLocalizedTextsUtil(typeInfo.getLabelBundle());
|
||||
// item.setType(textsUtil.getText(typeInfo.getLabelKey()));
|
||||
//
|
||||
// return item;
|
||||
// }
|
||||
//
|
||||
// @Transactional(Transactional.TxType.REQUIRED)
|
||||
// @Override
|
||||
// protected int sizeInBackEnd(final Query<BrowseDocumentsItem, String> query) {
|
||||
//
|
||||
// final Folder folder;
|
||||
// if (currentFolder == null) {
|
||||
// folder = controller.getCurrentSection().getRootDocumentsFolder();
|
||||
// } else {
|
||||
// folder = currentFolder;
|
||||
// }
|
||||
//
|
||||
// final int subFolderCount = countSubFolder(folder, query.getFilter());
|
||||
// final int itemCount = countItems(folder, query.getFilter());
|
||||
//
|
||||
// return subFolderCount + itemCount;
|
||||
// }
|
||||
//
|
||||
// private int countSubFolder(final Folder folder,
|
||||
// final Optional<String> filter) {
|
||||
//
|
||||
// final CriteriaBuilder builder = entityManager
|
||||
// .getCriteriaBuilder();
|
||||
// final CriteriaQuery<Long> query = builder.createQuery(Long.class);
|
||||
// final Root<Folder> from = query.from(Folder.class);
|
||||
//
|
||||
// query.select(builder.count(from));
|
||||
//
|
||||
// if (filter.isPresent()) {
|
||||
// query.where(builder
|
||||
// .and(builder.equal(from.get("parentCategory"), folder),
|
||||
// builder.or(
|
||||
// builder.like(builder.lower(from.get("name")),
|
||||
// String.format("%s%%", filter.get())),
|
||||
// builder.like(builder.lower(from.get("displayName")),
|
||||
// String.format("%s%%", filter.get())))));
|
||||
// } else {
|
||||
// query.where(builder.equal(from.get("parentCategory"), folder));
|
||||
// }
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(query)
|
||||
// .getSingleResult()
|
||||
// .intValue();
|
||||
// }
|
||||
//
|
||||
// private int countItems(final Folder folder,
|
||||
// final Optional<String> filter) {
|
||||
//
|
||||
// final CriteriaBuilder builder = entityManager
|
||||
// .getCriteriaBuilder();
|
||||
// final CriteriaQuery<Long> query = builder.createQuery(Long.class);
|
||||
// final Root<ContentItem> from = query.from(ContentItem.class);
|
||||
// final Join<ContentItem, Categorization> join = from.join("categories");
|
||||
//
|
||||
// query.select(builder.count(from));
|
||||
//
|
||||
// if (filter.isPresent()) {
|
||||
// query.where(builder
|
||||
// .and(builder.equal(join.get("category"), folder),
|
||||
// builder.or(
|
||||
// builder.like(builder.lower(from.get("name")),
|
||||
// String.format("%s%%", filter.get())),
|
||||
// builder.like(builder.lower(from.get("displayName")),
|
||||
// String.format("%s%%", filter.get())))));
|
||||
//
|
||||
// } else {
|
||||
// query.where(builder.equal(join.get("category"), folder));
|
||||
// }
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(query)
|
||||
// .getSingleResult()
|
||||
// .intValue();
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider;
|
||||
import com.vaadin.data.provider.HierarchicalQuery;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contentsection.FolderRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
* Data provider for the tree component of the {@link BrowseDocuments}
|
||||
* component.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class FolderBrowserFolderTreeDataProvider
|
||||
extends AbstractBackEndHierarchicalDataProvider<Folder, String> {
|
||||
|
||||
private static final long serialVersionUID = 5330319780008907163L;
|
||||
|
||||
@Inject
|
||||
private ContentSectionViewState contentSectionViewState;
|
||||
|
||||
@Inject
|
||||
private FolderRepository folderRepo;
|
||||
|
||||
@Inject
|
||||
private ContentSectionRepository sectionRepo;
|
||||
|
||||
@Override
|
||||
protected Stream<Folder> fetchChildrenFromBackEnd(
|
||||
HierarchicalQuery<Folder, String> query) {
|
||||
|
||||
final Optional<Folder> selectedParent = query.getParentOptional();
|
||||
|
||||
final Folder parent;
|
||||
if (selectedParent.isPresent()) {
|
||||
parent = folderRepo
|
||||
.findById(selectedParent.get().getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No folder with ID %d in the database.",
|
||||
selectedParent.get().getObjectId())));
|
||||
|
||||
return folderRepo.findSubFolders(parent).stream();
|
||||
} else {
|
||||
final ContentSection section = sectionRepo
|
||||
.findById(contentSectionViewState
|
||||
.getSelectedContentSection()
|
||||
.getObjectId())
|
||||
.orElseThrow(() -> new UnexpectedErrorException(String
|
||||
.format("No ContentSection with ID %d in the database.",
|
||||
contentSectionViewState
|
||||
.getSelectedContentSection()
|
||||
.getObjectId())));
|
||||
|
||||
final List<Folder> result = new ArrayList<>();
|
||||
result.add(section.getRootDocumentsFolder());
|
||||
return result.stream();
|
||||
}
|
||||
|
||||
// return folderRepo.findSubFolders(parent).stream();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int getChildCount(
|
||||
final HierarchicalQuery<Folder, String> query) {
|
||||
|
||||
final Optional<Folder> selectedParent = query.getParentOptional();
|
||||
|
||||
final Folder parent;
|
||||
if (selectedParent.isPresent()) {
|
||||
parent = folderRepo
|
||||
.findById(selectedParent.get().getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No folder with ID %d in the database.",
|
||||
selectedParent.get().getObjectId())));
|
||||
|
||||
return (int) folderRepo.countSubFolders(parent);
|
||||
} else {
|
||||
// final ContentSection section = sectionRepo
|
||||
// .findById(contentSectionViewState
|
||||
// .getSelectedContentSection()
|
||||
// .getObjectId())
|
||||
// .orElseThrow(() -> new UnexpectedErrorException(String
|
||||
// .format("No ContentSection with ID %d in the database.",
|
||||
// contentSectionViewState
|
||||
// .getSelectedContentSection()
|
||||
// .getObjectId())));
|
||||
//
|
||||
// parent = section.getRootDocumentsFolder();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// return (int) folderRepo.countSubFolders(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(final Folder item) {
|
||||
return folderRepo.countSubFolders(item) > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public final class FolderBrowserItem implements
|
||||
Comparable<FolderBrowserItem> {
|
||||
|
||||
private long itemId;
|
||||
|
||||
private String name;
|
||||
|
||||
private String title;
|
||||
|
||||
private String type;
|
||||
|
||||
private boolean folder;
|
||||
|
||||
private Date creationDate;
|
||||
|
||||
private Date lastModified;
|
||||
|
||||
public long getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public void setItemId(final long itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(final String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
public void setFolder(final boolean folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
public Date getCreationDate() {
|
||||
if (creationDate == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Date(creationDate.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void setCreationDate(final Date creationDate) {
|
||||
if (creationDate != null) {
|
||||
this.creationDate = new Date(creationDate.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public Date getLastModified() {
|
||||
if (lastModified == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Date(lastModified.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public void setLastModified(final Date lastModified) {
|
||||
if (lastModified != null) {
|
||||
this.lastModified = new Date(lastModified.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final FolderBrowserItem other) {
|
||||
|
||||
int result = title.compareTo(other.getTitle());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = name.compareTo(other.getName());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = type.compareTo(other.getType());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = lastModified.compareTo(other.getLastModified());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return creationDate.compareTo(other.getCreationDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 53 * hash + (int) (itemId ^ (itemId >>> 32));
|
||||
hash = 53 * hash + Objects.hashCode(name);
|
||||
hash = 53 * hash + Objects.hashCode(title);
|
||||
hash = 53 * hash + Objects.hashCode(type);
|
||||
hash = 53 * hash + (folder ? 1 : 0);
|
||||
hash = 53 * hash + Objects.hashCode(creationDate);
|
||||
hash = 53 * hash + Objects.hashCode(lastModified);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof FolderBrowserItem)) {
|
||||
return false;
|
||||
}
|
||||
final FolderBrowserItem other = (FolderBrowserItem) obj;
|
||||
if (itemId != other.getItemId()) {
|
||||
return false;
|
||||
}
|
||||
if (folder != other.isFolder()) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(name, other.getName())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(title, other.getTitle())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(type, other.getType())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(creationDate, other.getCreationDate())) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(lastModified, other.getLastModified());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s{ "
|
||||
+ "itemId = %d, "
|
||||
+ "name = \"%s\", "
|
||||
+ "title = \"%s\", "
|
||||
+ "type = \"%s\", "
|
||||
+ "creationDate = %s, "
|
||||
+ "lastChanged = %s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
itemId,
|
||||
name,
|
||||
title,
|
||||
type,
|
||||
Objects.toString(creationDate),
|
||||
Objects.toString(lastModified));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.CDIView;
|
||||
import org.libreccm.ui.AbstractLoginView;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@CDIView(value = LoginView.VIEWNAME,
|
||||
uis = {CmsUI.class})
|
||||
public class LoginView extends AbstractLoginView {
|
||||
|
||||
private static final long serialVersionUID = -8076055152219333275L;
|
||||
|
||||
public static final String VIEWNAME = "cmslogin";
|
||||
|
||||
@Override
|
||||
protected String getTargetView() {
|
||||
return CmsView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PageModelSelectDataProvider
|
||||
extends AbstractBackEndDataProvider<PageModel, String> {
|
||||
|
||||
private static final long serialVersionUID = 3102935928982631262L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
protected Stream<PageModel> fetchFromBackEnd(
|
||||
final Query<PageModel, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<PageModel> criteriaQuery = builder
|
||||
.createQuery(PageModel.class);
|
||||
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
|
||||
criteriaQuery.select(from);
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<PageModel, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
|
||||
|
||||
criteriaQuery.select(builder.count(from));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider;
|
||||
import com.vaadin.data.provider.HierarchicalQuery;
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.Domain;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PagesCategoryTreeDataProvider
|
||||
extends AbstractBackEndHierarchicalDataProvider<Category, String> {
|
||||
|
||||
private static final long serialVersionUID = -4953505403671944088L;
|
||||
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
|
||||
private Domain domain;
|
||||
|
||||
protected Domain getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
protected void setDomain(final Domain domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
protected Stream<Category> fetchChildrenFromBackEnd(
|
||||
final HierarchicalQuery<Category, String> query) {
|
||||
|
||||
if (query.getParentOptional().isPresent()) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Category> criteriaQuery = builder
|
||||
.createQuery(Category.class);
|
||||
|
||||
final Root<Category> from = criteriaQuery.from(Category.class);
|
||||
criteriaQuery.where(builder.equal(from.get("parentCategory"),
|
||||
query.getParentOptional().get()));
|
||||
final TypedQuery<Category> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
return entityQuery
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList()
|
||||
.stream();
|
||||
} else {
|
||||
|
||||
return Stream.of(domain.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int getChildCount(
|
||||
final HierarchicalQuery<Category, String> query) {
|
||||
|
||||
if (query.getParentOptional().isPresent()) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<Category> from = criteriaQuery.from(Category.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.where(builder.equal(from.get("parentCategory"),
|
||||
query.getParentOptional().get()));
|
||||
final TypedQuery<Long> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
return entityQuery.getSingleResult().intValue();
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public boolean hasChildren(final Category item) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<Category> from = criteriaQuery.from(Category.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.where(builder.equal(from.get("parentCategory"), item));
|
||||
final TypedQuery<Long> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
return entityQuery.getSingleResult().intValue() > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.categorization.CategoryRepository;
|
||||
import org.libreccm.categorization.Domain;
|
||||
import org.libreccm.categorization.DomainRepository;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.libreccm.sites.SiteRepository;
|
||||
import org.librecms.pages.Page;
|
||||
import org.librecms.pages.PageManager;
|
||||
import org.librecms.pages.PageRepository;
|
||||
import org.librecms.pages.Pages;
|
||||
import org.librecms.pages.PagesManager;
|
||||
import org.librecms.pages.PagesRepository;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PagesController {
|
||||
|
||||
@Inject
|
||||
private CategoryRepository categoryRepo;
|
||||
|
||||
@Inject
|
||||
private DomainRepository domainRepo;
|
||||
|
||||
@Inject
|
||||
private PageModelSelectDataProvider pageModelSelectDataProvider;
|
||||
|
||||
@Inject
|
||||
private PageManager pageManager;
|
||||
|
||||
@Inject
|
||||
private PageRepository pageRepo;
|
||||
|
||||
@Inject
|
||||
private PagesCategoryTreeDataProvider pagesCategoryTreeDataProvider;
|
||||
|
||||
@Inject
|
||||
private PagesEditorDomainSelectDataProvider pagesEditorDomainSelectDataProvider;
|
||||
|
||||
@Inject
|
||||
private PagesEditorSiteSelectDataProvider pagesEditorSiteSelectDataProvider;
|
||||
|
||||
@Inject
|
||||
private PagesGridDataProvider pagesGridDataProvider;
|
||||
|
||||
@Inject
|
||||
private PagesManager pagesManager;
|
||||
|
||||
@Inject
|
||||
private PagesRepository pagesRepo;
|
||||
|
||||
@Inject
|
||||
private SiteRepository siteRepo;
|
||||
|
||||
protected PageModelSelectDataProvider getPageModelSelectDataProvider() {
|
||||
return pageModelSelectDataProvider;
|
||||
}
|
||||
|
||||
protected PageManager getPageManager() {
|
||||
return pageManager;
|
||||
}
|
||||
|
||||
protected PageRepository getPageRepo() {
|
||||
return pageRepo;
|
||||
}
|
||||
|
||||
protected PagesCategoryTreeDataProvider getPagesCategoryTreeDataProvider() {
|
||||
return pagesCategoryTreeDataProvider;
|
||||
}
|
||||
|
||||
protected PagesEditorDomainSelectDataProvider getPagesEditorDomainSelectDataProvider() {
|
||||
return pagesEditorDomainSelectDataProvider;
|
||||
}
|
||||
|
||||
protected PagesEditorSiteSelectDataProvider getPagesEditorSiteSelectDataProvider() {
|
||||
return pagesEditorSiteSelectDataProvider;
|
||||
}
|
||||
|
||||
protected PagesGridDataProvider getPagesGridDataProvider() {
|
||||
return pagesGridDataProvider;
|
||||
}
|
||||
|
||||
protected PagesManager getPagesManager() {
|
||||
return pagesManager;
|
||||
}
|
||||
|
||||
protected PagesRepository getPagesRepo() {
|
||||
return pagesRepo;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected Optional<Page> findPage(final Category category) {
|
||||
|
||||
Objects.requireNonNull(category);
|
||||
|
||||
final Category theCategory = categoryRepo
|
||||
.findById(category.getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Category with ID %d in the database.",
|
||||
category.getObjectId())));
|
||||
|
||||
return pageRepo.findPageForCategory(theCategory);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected Pages createPages(final String name,
|
||||
final Site site,
|
||||
final Domain domain) {
|
||||
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(site);
|
||||
Objects.requireNonNull(domain);
|
||||
|
||||
if (name.isEmpty()
|
||||
|| name.matches("\\s*")) {
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
"The name of a Pages instance can't be empty.");
|
||||
}
|
||||
|
||||
final Site forSite = siteRepo
|
||||
.findById(site.getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Site with ID %d in the database.",
|
||||
site.getObjectId())));
|
||||
|
||||
final Domain withDomain = domainRepo
|
||||
.findById(domain.getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Domain with ID %d in the database.",
|
||||
domain.getObjectId())));
|
||||
|
||||
return pagesManager.createPages(name, forSite, withDomain);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.event.selection.SingleSelectionEvent;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.HorizontalSplitPanel;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.Tree;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.categorization.Category;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pages.Page;
|
||||
import org.librecms.pages.PageManager;
|
||||
import org.librecms.pages.Pages;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PagesDetails extends Window {
|
||||
|
||||
private static final long serialVersionUID = 6306677625483502088L;
|
||||
|
||||
private final CmsViewController controller;
|
||||
private final Pages pages;
|
||||
|
||||
private final GlobalizationHelper globalizationHelper;
|
||||
private final LocalizedTextsUtil textsUtil;
|
||||
|
||||
private Category selectedCategory;
|
||||
|
||||
private final Panel panel;
|
||||
private final ComboBox<PageModel> indexPageModelSelect;
|
||||
private final ComboBox<PageModel> itemPageModelSelect;
|
||||
|
||||
private final Button saveButton;
|
||||
private final Button cancelButton;
|
||||
|
||||
public PagesDetails(final Pages pages, final CmsViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
globalizationHelper = controller.getGlobalizationHelper();
|
||||
textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
this.pages = pages;
|
||||
this.controller = controller;
|
||||
|
||||
final PagesCategoryTreeDataProvider treeDataProvider = controller
|
||||
.getPagesController()
|
||||
.getPagesCategoryTreeDataProvider();
|
||||
treeDataProvider.setDomain(pages.getCategoryDomain());
|
||||
final Tree<Category> categoryTree = new Tree<>();
|
||||
categoryTree.setDataProvider(treeDataProvider);
|
||||
categoryTree.addItemClickListener(this::categoryTreeClicked);
|
||||
categoryTree.setItemCaptionGenerator(this::createCategoryTreeCaption);
|
||||
|
||||
indexPageModelSelect = new ComboBox<>(textsUtil
|
||||
.getText("cms.ui.pages.pagemodels.index_page"));
|
||||
indexPageModelSelect.setDataProvider(controller
|
||||
.getPagesController()
|
||||
.getPageModelSelectDataProvider());
|
||||
indexPageModelSelect
|
||||
.setItemCaptionGenerator(this::createPageModelCaption);
|
||||
indexPageModelSelect.setTextInputAllowed(false);
|
||||
indexPageModelSelect.setEmptySelectionAllowed(true);
|
||||
indexPageModelSelect.setEmptySelectionCaption(textsUtil
|
||||
.getText("cms.ui.pages.assigned_page_model.inherit"));
|
||||
indexPageModelSelect
|
||||
.setItemCaptionGenerator(this::createPageModelCaption);
|
||||
|
||||
itemPageModelSelect = new ComboBox<>(textsUtil
|
||||
.getText("cms.ui.pages.pagemodels.item_page"));
|
||||
itemPageModelSelect.setDataProvider(controller
|
||||
.getPagesController()
|
||||
.getPageModelSelectDataProvider());
|
||||
itemPageModelSelect
|
||||
.setItemCaptionGenerator(this::createPageModelCaption);
|
||||
itemPageModelSelect.setTextInputAllowed(false);
|
||||
itemPageModelSelect.setEmptySelectionAllowed(true);
|
||||
itemPageModelSelect.setEmptySelectionCaption(textsUtil
|
||||
.getText("cms.ui.pages.assigned_page_model.inherit"));
|
||||
|
||||
indexPageModelSelect.addSelectionListener(this::selectionChange);
|
||||
itemPageModelSelect.addSelectionListener(this::selectionChange);
|
||||
|
||||
saveButton = new Button(textsUtil
|
||||
.getText("cms.ui.pages.pagemodels.save"));
|
||||
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
||||
saveButton.addClickListener(this::saveButtonClicked);
|
||||
|
||||
cancelButton = new Button(textsUtil
|
||||
.getText("cms.ui.pages.pagemodels.cancel"));
|
||||
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
|
||||
cancelButton.addClickListener(this::cancelButtonClicked);
|
||||
|
||||
saveButton.setEnabled(false);
|
||||
cancelButton.setEnabled(false);
|
||||
|
||||
super.setCaption(textsUtil.getText("cms.ui.pages.title",
|
||||
new String[]{pages.getPrimaryUrl()}));
|
||||
|
||||
panel = new Panel(new VerticalLayout(
|
||||
new FormLayout(indexPageModelSelect,
|
||||
itemPageModelSelect),
|
||||
new HorizontalLayout(saveButton, cancelButton)));
|
||||
final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(
|
||||
categoryTree, panel);
|
||||
splitPanel.setSplitPosition(25.0f);
|
||||
super.setContent(splitPanel);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
||||
selectedCategory = pages.getCategoryDomain().getRoot();
|
||||
updateWidgets(selectedCategory);
|
||||
}
|
||||
|
||||
private String createCategoryTreeCaption(final Category category) {
|
||||
|
||||
if (category.getTitle().getValues().isEmpty()) {
|
||||
return category.getName();
|
||||
} else {
|
||||
|
||||
return globalizationHelper
|
||||
.getValueFromLocalizedString(category.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
private String createPageModelCaption(final PageModel pageModel) {
|
||||
|
||||
if (pageModel.getTitle().getValues().isEmpty()) {
|
||||
return pageModel.getName();
|
||||
} else {
|
||||
return globalizationHelper
|
||||
.getValueFromLocalizedString(pageModel.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
private void categoryTreeClicked(
|
||||
final Tree.ItemClick<Category> event) {
|
||||
|
||||
final Category category = event.getItem();
|
||||
selectedCategory = category;
|
||||
updateWidgets(category);
|
||||
}
|
||||
|
||||
private void selectionChange(final SingleSelectionEvent<PageModel> event) {
|
||||
|
||||
saveButton.setEnabled(true);
|
||||
cancelButton.setEnabled(true);
|
||||
}
|
||||
|
||||
private void updateWidgets(final Category category) {
|
||||
|
||||
Objects.requireNonNull(category);
|
||||
|
||||
final Optional<Page> page = controller
|
||||
.getPagesController()
|
||||
.findPage(category);
|
||||
|
||||
if (page.isPresent()) {
|
||||
panel.setCaption(textsUtil
|
||||
.getText("cms.ui.pages.page_config_for_category",
|
||||
new String[]{globalizationHelper
|
||||
.getValueFromLocalizedString(category
|
||||
.getTitle())}));
|
||||
indexPageModelSelect.setSelectedItem(page.get().getIndexPageModel());
|
||||
itemPageModelSelect.setSelectedItem(page.get().getItemPageModel());
|
||||
// indexPageModelSelect.setValue(page.get().getIndexPageModel());
|
||||
// itemPageModelSelect.setValue(page.get().getItemPageModel());
|
||||
} else {
|
||||
indexPageModelSelect.setSelectedItem(null);
|
||||
itemPageModelSelect.setSelectedItem(null);
|
||||
}
|
||||
|
||||
saveButton.setEnabled(false);
|
||||
cancelButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void saveButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final Page page = findOrCreatePage();
|
||||
|
||||
final Optional<PageModel> selectedIndexPageModel
|
||||
= indexPageModelSelect
|
||||
.getSelectedItem();
|
||||
if (selectedIndexPageModel.isPresent()) {
|
||||
page.setIndexPageModel(selectedIndexPageModel.get());
|
||||
} else {
|
||||
page.setIndexPageModel(null);
|
||||
}
|
||||
|
||||
final Optional<PageModel> selectedItemPageModel
|
||||
= itemPageModelSelect
|
||||
.getSelectedItem();
|
||||
if (selectedItemPageModel.isPresent()) {
|
||||
page.setItemPageModel(selectedItemPageModel.get());
|
||||
} else {
|
||||
page.setItemPageModel(null);
|
||||
}
|
||||
|
||||
controller.getPagesController().getPageRepo().save(page);
|
||||
updateWidgets(selectedCategory);
|
||||
}
|
||||
|
||||
private Page findOrCreatePage() {
|
||||
|
||||
final Optional<Page> page = controller
|
||||
.getPagesController()
|
||||
.findPage(selectedCategory);
|
||||
|
||||
if (page.isPresent()) {
|
||||
return page.get();
|
||||
} else {
|
||||
|
||||
final PageManager pageManager = controller
|
||||
.getPagesController()
|
||||
.getPageManager();
|
||||
return pageManager.createPageForCategory(selectedCategory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void cancelButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
updateWidgets(selectedCategory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.categorization.Domain;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pages.Pages;
|
||||
import org.librecms.pages.PagesManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PagesEditor extends Window {
|
||||
|
||||
private static final long serialVersionUID = -7895690663139812879L;
|
||||
|
||||
private final CmsViewController controller;
|
||||
private final LocalizedTextsUtil textsUtil;
|
||||
|
||||
private Pages pages;
|
||||
|
||||
private final TextField nameField;
|
||||
private final ComboBox<Site> siteSelect;
|
||||
private final ComboBox<Domain> categorySystemSelect;
|
||||
|
||||
PagesEditor(final CmsViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
nameField = new TextField(textsUtil
|
||||
.getText("cms.ui.pages.form.primary_url_field.label"));
|
||||
|
||||
siteSelect = new ComboBox<>(textsUtil
|
||||
.getText("cms.ui.pages.form.site_select.error"));
|
||||
siteSelect.setDataProvider(controller
|
||||
.getPagesController()
|
||||
.getPagesEditorSiteSelectDataProvider());
|
||||
siteSelect.setEmptySelectionAllowed(false);
|
||||
siteSelect.setItemCaptionGenerator(this::buildSiteCaption);
|
||||
|
||||
categorySystemSelect = new ComboBox<>(textsUtil
|
||||
.getText("cms.ui.pages.form.category_domain_select.label"));
|
||||
categorySystemSelect.setEmptySelectionAllowed(false);
|
||||
categorySystemSelect.setDataProvider(controller
|
||||
.getPagesController()
|
||||
.getPagesEditorDomainSelectDataProvider());
|
||||
categorySystemSelect.setItemCaptionGenerator(Domain::getDomainKey);
|
||||
|
||||
final FormLayout formLayout = new FormLayout(nameField,
|
||||
siteSelect,
|
||||
categorySystemSelect);
|
||||
|
||||
final Button saveButton = new Button(textsUtil
|
||||
.getText("cms.ui.pages.editor.save"));
|
||||
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
||||
saveButton.addClickListener(this::saveButtonClicked);
|
||||
|
||||
final Button cancelButton = new Button(textsUtil
|
||||
.getText("cms.ui.pages.editor.cancel"));
|
||||
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
|
||||
cancelButton.addClickListener(event -> close());
|
||||
|
||||
super.setContent(new VerticalLayout(formLayout,
|
||||
new HorizontalLayout(saveButton,
|
||||
cancelButton)));
|
||||
}
|
||||
|
||||
PagesEditor(final Pages pages,
|
||||
final CmsViewController controller) {
|
||||
|
||||
this(controller);
|
||||
|
||||
this.pages = pages;
|
||||
|
||||
nameField.setValue(pages.getPrimaryUrl());
|
||||
siteSelect.setEnabled(false);
|
||||
categorySystemSelect.setEnabled(false);
|
||||
}
|
||||
|
||||
private String buildSiteCaption(final Site site) {
|
||||
|
||||
if (site.isDefaultSite()) {
|
||||
return String.format("%s *",
|
||||
site.getDomainOfSite());
|
||||
} else {
|
||||
return site.getDomainOfSite();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
if (nameField.getValue() == null
|
||||
|| nameField.getValue().isEmpty()
|
||||
|| nameField.getValue().matches("\\s*")) {
|
||||
|
||||
nameField.setComponentError(new UserError(textsUtil
|
||||
.getText("cms.ui.pages.form.primary_url_field.error")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pages == null
|
||||
&& !siteSelect.getSelectedItem().isPresent()) {
|
||||
|
||||
siteSelect.setComponentError(new UserError(textsUtil
|
||||
.getText("cms.ui.pages.form.site_select.error")));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (pages == null
|
||||
&& !categorySystemSelect.getSelectedItem().isPresent()) {
|
||||
|
||||
categorySystemSelect.setComponentError(new UserError(textsUtil
|
||||
.getText("cms.ui.pages.form.category_domain_select.error")));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (pages == null) {
|
||||
final PagesController pagesController = controller
|
||||
.getPagesController();
|
||||
|
||||
pages = pagesController
|
||||
.createPages(generatePrimaryUrl(nameField.getValue()),
|
||||
siteSelect.getValue(),
|
||||
categorySystemSelect.getValue());
|
||||
} else {
|
||||
|
||||
pages.setPrimaryUrl(generatePrimaryUrl(nameField.getValue()));
|
||||
controller.getPagesController().getPagesRepo().save(pages);
|
||||
}
|
||||
|
||||
controller.getPagesController().getPagesGridDataProvider().refreshAll();
|
||||
close();
|
||||
}
|
||||
|
||||
private String generatePrimaryUrl(final String name) {
|
||||
|
||||
if (name.startsWith("/") && name.endsWith("/")) {
|
||||
return name;
|
||||
} else if (name.startsWith("/") && !name.endsWith("/")) {
|
||||
return String.format("%s/", name);
|
||||
} else if (!name.startsWith("/") && name.endsWith("/")) {
|
||||
return String.format("/%s", name);
|
||||
} else {
|
||||
return String.format("/%s/", name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.categorization.Domain;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PagesEditorDomainSelectDataProvider
|
||||
extends AbstractBackEndDataProvider<Domain, String> {
|
||||
|
||||
private static final long serialVersionUID = 7172310455833118907L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
protected Stream<Domain> fetchFromBackEnd(
|
||||
final Query<Domain, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Domain> criteriaQuery = builder
|
||||
.createQuery(Domain.class);
|
||||
|
||||
final Root<Domain> from = criteriaQuery.from(Domain.class);
|
||||
if (query.getFilter().isPresent()) {
|
||||
criteriaQuery.where(builder.like(from.get("domainKey"),
|
||||
":filter%"));
|
||||
}
|
||||
|
||||
final TypedQuery<Domain> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
entityQuery.setParameter("filter", query.getFilter().get());
|
||||
}
|
||||
|
||||
return entityQuery
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<Domain, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<Domain> from = criteriaQuery.from(Domain.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
if (query.getFilter().isPresent()) {
|
||||
criteriaQuery.where(builder.like(from.get("domainKey"),
|
||||
":filter%"));
|
||||
}
|
||||
|
||||
final TypedQuery<Long> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
entityQuery.setParameter("filter", query.getFilter().get());
|
||||
}
|
||||
|
||||
return entityQuery.getSingleResult().intValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.sites.Site;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class PagesEditorSiteSelectDataProvider extends AbstractBackEndDataProvider<Site, String> {
|
||||
|
||||
private static final long serialVersionUID = 8334700797163099258L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Override
|
||||
protected Stream<Site> fetchFromBackEnd(final Query<Site, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Site> criteriaQuery = builder
|
||||
.createQuery(Site.class);
|
||||
|
||||
final Root<Site> from = criteriaQuery.from(Site.class);
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
criteriaQuery.where(builder.like(from.get("domainOfSite"),
|
||||
":filter%"));
|
||||
}
|
||||
|
||||
final TypedQuery<Site> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
entityQuery.setParameter("filter", query.getFilter().get());
|
||||
}
|
||||
|
||||
return entityQuery
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<Site, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<Site> from = criteriaQuery.from(Site.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
criteriaQuery.where(builder.like(from.get("domainOfSite"),
|
||||
":filter%"));
|
||||
}
|
||||
|
||||
final TypedQuery<Long> entityQuery = entityManager
|
||||
.createQuery(criteriaQuery);
|
||||
|
||||
if (query.getFilter().isPresent()) {
|
||||
entityQuery.setParameter("filter", query.getFilter().get());
|
||||
}
|
||||
|
||||
return entityQuery.getSingleResult().intValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.librecms.pages.Pages;
|
||||
import org.librecms.pages.PagesRepository;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class PagesGridDataProvider
|
||||
extends AbstractBackEndDataProvider<Pages, String> {
|
||||
|
||||
private static final long serialVersionUID = -2388748600960614488L;
|
||||
|
||||
@Inject
|
||||
private PagesRepository pagesRepo;
|
||||
|
||||
@Override
|
||||
protected Stream<Pages> fetchFromBackEnd(final Query<Pages, String> query) {
|
||||
|
||||
return pagesRepo
|
||||
.findAll()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<Pages, String> query) {
|
||||
|
||||
return pagesRepo.findAll().size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.ui.ConfirmDialog;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pages.Pages;
|
||||
import org.librecms.pages.PagesRepository;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PagesTab extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = 8237082714759130342L;
|
||||
|
||||
private static final String COL_NAME = "name";
|
||||
private static final String COL_SITE = "site";
|
||||
private static final String COL_EDIT = "edit";
|
||||
private static final String COL_DEL = "del";
|
||||
|
||||
private final CmsViewController controller;
|
||||
private final LocalizedTextsUtil textsUtil;
|
||||
|
||||
PagesTab(final CmsViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
final Grid<Pages> pagesGrid = new Grid<>();
|
||||
// pagesGrid
|
||||
// .addColumn(Pages::getPrimaryUrl)
|
||||
// .setCaption("cms.ui.contentcenter.pagestable.columns.name.header")
|
||||
// .setId(COL_NAME);
|
||||
pagesGrid
|
||||
.addComponentColumn(this::buildDetailsLink)
|
||||
.setCaption(textsUtil
|
||||
.getText("cms.ui.contentcenter.pagestable.columns.name.header"))
|
||||
.setId(COL_NAME);
|
||||
pagesGrid
|
||||
.addColumn(pages -> pages.getSite().getDomainOfSite())
|
||||
.setCaption(textsUtil
|
||||
.getText("cms.ui.contentcenter.pagestable.columns.site.header"))
|
||||
.setId(COL_SITE);
|
||||
pagesGrid
|
||||
.addComponentColumn(this::buildEditButton)
|
||||
.setCaption(textsUtil
|
||||
.getText("cms.ui.contentcenter.pagestable.columns.edit.header"))
|
||||
.setId(COL_EDIT);
|
||||
pagesGrid
|
||||
.addComponentColumn(this::buildDeleteButton)
|
||||
.setCaption(textsUtil
|
||||
.getText("cms.ui.contentcenter.pagestable.columns.delete.header"))
|
||||
.setId(COL_DEL);
|
||||
|
||||
final Button addPagesButton = new Button(textsUtil
|
||||
.getText("cms.ui.contentcenter.pages.add_link"));
|
||||
addPagesButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
addPagesButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
addPagesButton.addClickListener(this::addPagesButtonClicked);
|
||||
final HeaderRow headerRow = pagesGrid.prependHeaderRow();
|
||||
final HeaderCell headerCell = headerRow
|
||||
.join(COL_NAME, COL_SITE, COL_EDIT, COL_DEL);
|
||||
headerCell.setComponent(new HorizontalLayout(addPagesButton));
|
||||
|
||||
pagesGrid.setDataProvider(controller
|
||||
.getPagesController()
|
||||
.getPagesGridDataProvider());
|
||||
pagesGrid.setWidth("100%");
|
||||
|
||||
super.setCompositionRoot(new VerticalLayout(pagesGrid));
|
||||
}
|
||||
|
||||
private Component buildDetailsLink(final Pages pages) {
|
||||
|
||||
final Button button = new Button(pages.getPrimaryUrl());
|
||||
button.addStyleName(ValoTheme.BUTTON_LINK);
|
||||
button.addClickListener(event -> detailsLinkClicked(event, pages));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private Component buildEditButton(final Pages pages) {
|
||||
|
||||
final Button button = new Button(textsUtil
|
||||
.getText("cms.ui.contentcenter.pages.edit.label"));
|
||||
button.setIcon(VaadinIcons.EDIT);
|
||||
button.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
button.addClickListener(event -> editButtonClicked(event, pages));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private Component buildDeleteButton(final Pages pages) {
|
||||
|
||||
final Button button = new Button(textsUtil
|
||||
.getText("cms.ui.contentcenter.pages.delete.label"));
|
||||
button.setIcon(VaadinIcons.MINUS_CIRCLE_O);
|
||||
button.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
button.addClickListener(event -> deleteButtonClicked(event, pages));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private void addPagesButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final PagesEditor editor = new PagesEditor(controller);
|
||||
editor.setModal(true);
|
||||
editor.setWidth("40%");
|
||||
editor.setHeight("60%");
|
||||
|
||||
UI.getCurrent().addWindow(editor);
|
||||
}
|
||||
|
||||
private void detailsLinkClicked(final Button.ClickEvent event,
|
||||
final Pages pages) {
|
||||
|
||||
final PagesDetails pagesDetails = new PagesDetails(pages, controller);
|
||||
pagesDetails.setModal(true);
|
||||
pagesDetails.setWidth("90%");
|
||||
pagesDetails.setHeight("90%");
|
||||
|
||||
UI.getCurrent().addWindow(pagesDetails);
|
||||
}
|
||||
|
||||
private void editButtonClicked(final Button.ClickEvent event,
|
||||
final Pages pages) {
|
||||
|
||||
final PagesEditor pagesEditor = new PagesEditor(pages, controller);
|
||||
pagesEditor.setModal(true);
|
||||
pagesEditor.setWidth("40%");
|
||||
pagesEditor.setHeight("80%");
|
||||
|
||||
UI.getCurrent().addWindow(pagesEditor);
|
||||
}
|
||||
|
||||
private void deleteButtonClicked(final Button.ClickEvent event,
|
||||
final Pages pages) {
|
||||
|
||||
final ConfirmDialog confirmDialog
|
||||
= new ConfirmDialog(() -> deletePages(pages));
|
||||
confirmDialog.setMessage(textsUtil
|
||||
.getText("cms.ui.contentcenter.pages.delete.confirm"));
|
||||
confirmDialog.setModal(true);
|
||||
|
||||
UI.getCurrent().addWindow(confirmDialog);
|
||||
}
|
||||
|
||||
private Void deletePages(final Pages pages) {
|
||||
|
||||
final PagesRepository pagesRepo = controller
|
||||
.getPagesController()
|
||||
.getPagesRepo();
|
||||
|
||||
pagesRepo.delete(pages);
|
||||
controller
|
||||
.getPagesController()
|
||||
.getPagesGridDataProvider()
|
||||
.refreshAll();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.authoring;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.TextField;
|
||||
import org.libreccm.ui.LocalizedStringWidget;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.ui.ContentSectionViewController;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @param <T>
|
||||
*/
|
||||
public class BasicItemPropertiesStep<T extends ContentItem>
|
||||
extends CustomComponent
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3881230433270571344L;
|
||||
|
||||
private final ContentSectionViewController controller;
|
||||
private final ContentItem item;
|
||||
|
||||
private final TextField nameField;
|
||||
private final LocalizedStringWidget titleWidget;
|
||||
|
||||
public BasicItemPropertiesStep(final ContentSectionViewController controller,
|
||||
final T item) {
|
||||
|
||||
Objects.requireNonNull(controller);
|
||||
Objects.requireNonNull(item);
|
||||
|
||||
this.controller = controller;
|
||||
this.item = item;
|
||||
|
||||
nameField = new TextField("Name");
|
||||
nameField.setValue(item.getName().getValue());
|
||||
nameField.addValueChangeListener(event -> {
|
||||
});
|
||||
|
||||
titleWidget = new LocalizedStringWidget(
|
||||
controller.getLocalizedStringWidgetController(),
|
||||
item.getTitle(),
|
||||
false);
|
||||
titleWidget.setCaption("Title");
|
||||
|
||||
final Button saveButton = new Button("Save");
|
||||
saveButton.addClickListener(event -> {
|
||||
});
|
||||
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.addClickListener(event -> {
|
||||
});
|
||||
|
||||
final FormLayout layout = new FormLayout(nameField,
|
||||
titleWidget,
|
||||
saveButton,
|
||||
cancelButton);
|
||||
super.setCompositionRoot(layout);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.authoring;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.TextField;
|
||||
import org.libreccm.ui.LocalizedStringWidget;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.ui.ContentSectionViewController;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class BasicItemPropertiesWidget
|
||||
extends CustomComponent
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6560855454431178274L;
|
||||
|
||||
private final ContentSectionViewController controller;
|
||||
private final ContentItem item;
|
||||
|
||||
private final TextField nameField;
|
||||
private final LocalizedStringWidget titleWidget;
|
||||
|
||||
public BasicItemPropertiesWidget(
|
||||
final ContentSectionViewController controller,
|
||||
final ContentItem item) {
|
||||
|
||||
this.controller = controller;
|
||||
this.item = item;
|
||||
|
||||
this.nameField = new TextField("Title");
|
||||
nameField.setValue(item.getName().getValue());
|
||||
nameField.addValueChangeListener(this::nameValueChanged);
|
||||
|
||||
this.titleWidget = new LocalizedStringWidget(controller
|
||||
.getLocalizedStringWidgetController(),
|
||||
item.getTitle(),
|
||||
false);
|
||||
titleWidget.setCaption("Title");
|
||||
}
|
||||
|
||||
protected void nameValueChanged(
|
||||
final HasValue.ValueChangeEvent<String> event) {
|
||||
|
||||
final String result = nameField
|
||||
.getValue()
|
||||
.toLowerCase(Locale.ROOT)
|
||||
.replace(' ', '-')
|
||||
.replace('&', '-')
|
||||
.replace('/', '-')
|
||||
.replace('#', '-')
|
||||
.replace('?', '-')
|
||||
.replace("ä", "ae")
|
||||
.replace("ö", "oe")
|
||||
.replace("ü", "ue")
|
||||
.replace("ß", "ss")
|
||||
.replaceAll("-{2,}", "-");
|
||||
|
||||
nameField.setValue(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.authoring.article;
|
||||
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.TextField;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contenttypes.Article;
|
||||
import org.librecms.ui.ContentSectionViewController;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ArticlePropertiesStep
|
||||
extends CustomComponent
|
||||
implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1587965921855375545L;
|
||||
|
||||
private final ContentSectionViewController controller;
|
||||
private final Article article;
|
||||
|
||||
public ArticlePropertiesStep(final ContentSectionViewController controller,
|
||||
final ContentItem item) {
|
||||
|
||||
Objects.requireNonNull(controller);
|
||||
Objects.requireNonNull(item);
|
||||
|
||||
if (!(item instanceof Article)) {
|
||||
throw new IllegalArgumentException(String
|
||||
.format("The provided ContentItem is not an instance "
|
||||
+ "of class \"%s\" but of class \"%s\".",
|
||||
Article.class.getName(),
|
||||
item.getClass().getName()));
|
||||
}
|
||||
|
||||
this.controller = controller;
|
||||
article = (Article) item;
|
||||
|
||||
final TextField titleField = new TextField("Title");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import com.vaadin.ui.TextField;
|
||||
import org.libreccm.admin.ui.AbstractPageModelComponentEditor;
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pagemodel.ContentItemComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class AbstractContentItemComponentEditor<T extends ContentItemComponent>
|
||||
extends AbstractPageModelComponentEditor<T> {
|
||||
|
||||
private static final long serialVersionUID = -4872408582648018134L;
|
||||
|
||||
private final PageModelComponentEditorController controller;
|
||||
|
||||
private TextField modeField;
|
||||
|
||||
public AbstractContentItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public AbstractContentItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final T componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
modeField = new TextField(textsUtil
|
||||
.getText("cms.ui.pagemodel.contentitem_component_form.mode.label"));
|
||||
addComponent(modeField);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initWidgets() {
|
||||
|
||||
final T component = getComponentModel();
|
||||
|
||||
if (component != null) {
|
||||
modeField.setValue(component.getMode());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateComponentModel() {
|
||||
|
||||
final T component = getComponentModel();
|
||||
|
||||
component.setMode(modeField.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.pagemodel.CategorizedItemComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class CategorizedItemComponentEditor
|
||||
extends AbstractContentItemComponentEditor<CategorizedItemComponent> {
|
||||
|
||||
private static final long serialVersionUID = 7641211643041787151L;
|
||||
|
||||
public CategorizedItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
}
|
||||
|
||||
public CategorizedItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final CategorizedItemComponent componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validate() {
|
||||
//Nothing to validate here.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CategorizedItemComponent createComponentModel() {
|
||||
|
||||
return new CategorizedItemComponent();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import org.libreccm.admin.ui.AbstractPageModelComponentEditor;
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pagemodel.CategoryTreeComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class CategoryTreeComponentEditor
|
||||
extends AbstractPageModelComponentEditor<CategoryTreeComponent> {
|
||||
|
||||
private static final long serialVersionUID = -6162769539698324778L;
|
||||
|
||||
private final PageModelComponentEditorController controller;
|
||||
|
||||
private CheckBox showFullTreeCheckBox;
|
||||
|
||||
public CategoryTreeComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModelInfo,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModelInfo, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public CategoryTreeComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final CategoryTreeComponent componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
showFullTreeCheckBox = new CheckBox(textsUtil
|
||||
.getText(
|
||||
"cms.ui.pagemodel.category_tree_component_form.show_full_tree.label"));
|
||||
addComponent(showFullTreeCheckBox);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initWidgets() {
|
||||
|
||||
final CategoryTreeComponent component = getComponentModel();
|
||||
|
||||
if (component != null) {
|
||||
showFullTreeCheckBox.setValue(component.isShowFullTree());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validate() {
|
||||
|
||||
//Nothing to validate here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CategoryTreeComponent createComponentModel() {
|
||||
return new CategoryTreeComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateComponentModel() {
|
||||
|
||||
final CategoryTreeComponent component = getComponentModel();
|
||||
|
||||
component.setShowFullTree(showFullTreeCheckBox.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.pagemodel.FixedContentItemComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FixedContentItemComponentEditor
|
||||
extends AbstractContentItemComponentEditor<FixedContentItemComponent> {
|
||||
|
||||
private static final long serialVersionUID = 7641211643041787151L;
|
||||
|
||||
public FixedContentItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
}
|
||||
|
||||
public FixedContentItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final FixedContentItemComponent componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validate() {
|
||||
//Nothing to validate here.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FixedContentItemComponent createComponentModel() {
|
||||
|
||||
return new FixedContentItemComponent();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.pagemodel.GreetingItemComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class GreetingItemComponentEditor
|
||||
extends AbstractContentItemComponentEditor<GreetingItemComponent> {
|
||||
|
||||
private static final long serialVersionUID = 7641211643041787151L;
|
||||
|
||||
public GreetingItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
}
|
||||
|
||||
public GreetingItemComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final GreetingItemComponent componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validate() {
|
||||
//Nothing to validate here.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GreetingItemComponent createComponentModel() {
|
||||
|
||||
return new GreetingItemComponent();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.pagemodel;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import org.libreccm.admin.ui.AbstractPageModelComponentEditor;
|
||||
import org.libreccm.admin.ui.PageModelComponentEditorController;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.pagemodel.ItemListComponent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ItemListComponentEditor
|
||||
extends AbstractPageModelComponentEditor<ItemListComponent> {
|
||||
|
||||
private static final long serialVersionUID = 8607871974091248260L;
|
||||
|
||||
private final PageModelComponentEditorController controller;
|
||||
|
||||
private CheckBox descendingCheckBox;
|
||||
private TextField limitToTypeField;
|
||||
private TextField pageSizeField;
|
||||
private TextArea listOrderArea;
|
||||
|
||||
public ItemListComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModelInfo,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModelInfo, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public ItemListComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final ItemListComponent componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super(pageModel, componentModel, controller);
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
descendingCheckBox = new CheckBox(textsUtil
|
||||
.getText(
|
||||
"cms.ui.pagemodel.itemlist_component_form.descending.label"));
|
||||
addComponent(descendingCheckBox);
|
||||
|
||||
limitToTypeField = new TextField(textsUtil
|
||||
.getText(
|
||||
"cms.ui.pagemodel.itemlist_component_form.limit_to_type.label"));
|
||||
addComponent(limitToTypeField);
|
||||
|
||||
pageSizeField = new TextField(textsUtil
|
||||
.getText("cms.ui.pagemodel.itemlist_component_form.page_size.label"));
|
||||
pageSizeField.setValue("25");
|
||||
addComponent(pageSizeField);
|
||||
|
||||
listOrderArea = new TextArea(textsUtil
|
||||
.getText("cms.ui.pagemodel.itemlist_component_form.list_order.label"));
|
||||
addComponent(listOrderArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initWidgets() {
|
||||
|
||||
final ItemListComponent itemListComponent = getComponentModel();
|
||||
|
||||
if (itemListComponent != null) {
|
||||
descendingCheckBox.setValue(itemListComponent.isDescending());
|
||||
limitToTypeField.setValue(itemListComponent.getLimitToType());
|
||||
pageSizeField
|
||||
.setValue(Integer.toString(itemListComponent.getPageSize()));
|
||||
listOrderArea.setValue(String.join("\n",
|
||||
itemListComponent.getListOrder()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validate() {
|
||||
|
||||
final String pageSizeValue = pageSizeField.getValue();
|
||||
if (pageSizeValue != null
|
||||
&& !pageSizeValue.isEmpty()
|
||||
&& !pageSizeValue.matches("\\d*")) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(CmsConstants.CMS_BUNDLE);
|
||||
|
||||
pageSizeField.setComponentError(new UserError(textsUtil
|
||||
.getText(
|
||||
"cms.ui.pagemodel.itemlist_component_form.page_size.error.not_a_number")));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemListComponent createComponentModel() {
|
||||
return new ItemListComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateComponentModel() {
|
||||
|
||||
final ItemListComponent component = getComponentModel();
|
||||
|
||||
final boolean descending = descendingCheckBox.getValue();
|
||||
final String limitToType = limitToTypeField.getValue();
|
||||
final int pageSize = Integer.parseInt(pageSizeField.getValue());
|
||||
final List<String> listOrder = Arrays
|
||||
.stream(listOrderArea.getValue().split("\n"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
component.setDescending(descending);
|
||||
component.setLimitToType(limitToType);
|
||||
component.setPageSize(pageSize);
|
||||
component.setListOrder(listOrder);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -227,25 +227,6 @@
|
|||
<artifactId>Saxon-HE</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>
|
||||
<groupId>org.primefaces</groupId>
|
||||
<artifactId>primefaces</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!-- Vaadin dependencies for Vaadin prototype -->
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-themes</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-client-compiled</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-cdi</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Export Import Libraries -->
|
||||
|
||||
<dependency>
|
||||
|
|
@ -377,37 +358,6 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>resources</goal>
|
||||
<goal>update-theme</goal>
|
||||
<goal>update-widgetset</goal>
|
||||
<goal>compile-theme</goal>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!--<plugin>
|
||||
<groupId>org.jboss.tattletale</groupId>
|
||||
<artifactId>tattletale-maven</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>${project.build.directory}</source>
|
||||
<destination>${project.build.directory}/tattletale</destination>
|
||||
</configuration>
|
||||
</plugin>-->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
@ -481,7 +431,7 @@
|
|||
<linkXref>true</linkXref>
|
||||
<sourceEncoding>utf-8</sourceEncoding>
|
||||
<targetJdk>1.8</targetJdk>
|
||||
<!-- <rulesets>
|
||||
<!-- <rulesets>
|
||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||
<ruleset>/rulesets/java/braces.xml</ruleset>
|
||||
<ruleset>/rulesets/java/clone.xml</ruleset>
|
||||
|
|
|
|||
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.ComponentModel;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class AbstractPageModelComponentEditor<T extends ComponentModel>
|
||||
extends Window {
|
||||
|
||||
private static final long serialVersionUID = 7347805088308841378L;
|
||||
|
||||
private final PageModelComponentEditorController controller;
|
||||
private final PageModel pageModel;
|
||||
private PageModelComponentModel componentModelInfo;
|
||||
private T componentModel;
|
||||
|
||||
private final FormLayout formLayout;
|
||||
|
||||
private TextField keyField;
|
||||
|
||||
public AbstractPageModelComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final PageModelComponentModel componentModelInfo,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
this.pageModel = pageModel;
|
||||
this.componentModelInfo = componentModelInfo;
|
||||
|
||||
formLayout = new FormLayout();
|
||||
|
||||
createWidgets();
|
||||
}
|
||||
|
||||
public AbstractPageModelComponentEditor(
|
||||
final PageModel pageModel,
|
||||
final T componentModel,
|
||||
final PageModelComponentEditorController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.pageModel = pageModel;
|
||||
this.componentModel = componentModel;
|
||||
this.controller = controller;
|
||||
|
||||
formLayout = new FormLayout();
|
||||
|
||||
createWidgets();
|
||||
|
||||
keyField.setValue(componentModel.getKey());
|
||||
}
|
||||
|
||||
private void createWidgets() {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
keyField = new TextField(textsUtil.getText(
|
||||
"ui.admin.pagemodels.components.key.label"));
|
||||
addComponent(keyField);
|
||||
|
||||
final Button saveButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.components.save"));
|
||||
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
||||
saveButton.addClickListener(this::saveButtonClicked);
|
||||
|
||||
final Button cancelButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.components.cancel"));
|
||||
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
|
||||
cancelButton.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttonsLayout = new HorizontalLayout(saveButton,
|
||||
cancelButton);
|
||||
|
||||
setContent(new VerticalLayout(formLayout, buttonsLayout));
|
||||
}
|
||||
|
||||
private void saveButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final String key = keyField.getValue();
|
||||
if (key == null
|
||||
|| key.isEmpty()
|
||||
|| key.matches("\\s*")) {
|
||||
|
||||
keyField.setComponentError(new UserError(textsUtil
|
||||
.getText("ui.admin.pagemodels.components.key.error.not_empty")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (componentModel == null) {
|
||||
componentModel = createComponentModel();
|
||||
componentModel.setKey(key);
|
||||
updateComponentModel();
|
||||
// ToDo
|
||||
// controller
|
||||
// .getPageModelsController()
|
||||
// .addComponentModel(pageModel, componentModel);
|
||||
} else {
|
||||
componentModel.setKey(key);
|
||||
updateComponentModel();
|
||||
controller.getComponentModelRepository().save(componentModel);
|
||||
}
|
||||
controller.refreshComponentModels();
|
||||
close();
|
||||
}
|
||||
|
||||
protected PageModelComponentEditorController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
protected PageModelComponentModel getComponentModelInfo() {
|
||||
return componentModelInfo;
|
||||
}
|
||||
|
||||
protected T getComponentModel() {
|
||||
return componentModel;
|
||||
}
|
||||
|
||||
protected final void addComponent(final Component component) {
|
||||
|
||||
formLayout.addComponent(component);
|
||||
}
|
||||
|
||||
protected abstract void initWidgets();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {@code true} if form is validate, {@code false} if not.
|
||||
*/
|
||||
protected abstract boolean validate();
|
||||
|
||||
protected abstract T createComponentModel();
|
||||
|
||||
protected abstract void updateComponentModel();
|
||||
|
||||
}
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.annotations.Theme;
|
||||
import com.vaadin.cdi.CDIUI;
|
||||
import com.vaadin.cdi.CDIViewProvider;
|
||||
import com.vaadin.cdi.URLMapping;
|
||||
import com.vaadin.navigator.Navigator;
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import com.vaadin.server.VaadinRequest;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.UI;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@URLMapping("vaadin")
|
||||
@CDIUI("admin")
|
||||
@Theme("ccm-core")
|
||||
public class AdminUIVaadin extends UI {
|
||||
|
||||
private static final long serialVersionUID = -1352590567964037112L;
|
||||
|
||||
// private TabSheet tabSheet;
|
||||
// @Inject
|
||||
// private UserRepository userRepo;
|
||||
@Inject
|
||||
private CDIViewProvider viewProvider;
|
||||
|
||||
@Inject
|
||||
private Subject subject;
|
||||
|
||||
@Inject
|
||||
private PermissionChecker permissionChecker;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Override
|
||||
protected void init(VaadinRequest request) {
|
||||
|
||||
final Navigator navigator = new Navigator(this, this);
|
||||
navigator.addProvider(viewProvider);
|
||||
|
||||
setLocale(globalizationHelper.getNegotiatedLocale());
|
||||
|
||||
navigator.addViewChangeListener(new AuthNavListener());
|
||||
|
||||
if (subject.isAuthenticated()) {
|
||||
navigator.navigateTo(AdminView.VIEWNAME);
|
||||
} else {
|
||||
navigator.navigateTo(LoginView.VIEWNAME);
|
||||
}
|
||||
|
||||
// tabSheet = new TabSheet();
|
||||
//
|
||||
// final TabSheet userGroupsRoles = new TabSheet();
|
||||
// final Grid<User> usersTable = new Grid<>();
|
||||
// usersTable.setItems(userRepo.findAll());
|
||||
// usersTable.addColumn(User::getName).setCaption("User name");
|
||||
// usersTable.addColumn(User::getGivenName).setCaption("Given name");
|
||||
// usersTable.addColumn(User::getFamilyName).setCaption("Family name");
|
||||
// usersTable
|
||||
// .addColumn(user -> user.getPrimaryEmailAddress().getAddress())
|
||||
// .setCaption("E-Mail");
|
||||
// usersTable.addColumn(User::isBanned).setCaption("Banned?");
|
||||
// userGroupsRoles.addTab(usersTable, "Users");
|
||||
//
|
||||
// tabSheet.addTab(userGroupsRoles, "Users/Groups/Roles");
|
||||
// setContent(tabSheet);
|
||||
}
|
||||
|
||||
private class AuthNavListener implements ViewChangeListener {
|
||||
|
||||
private static final long serialVersionUID = -693722234602948170L;
|
||||
|
||||
@Override
|
||||
public boolean beforeViewChange(final ViewChangeEvent event) {
|
||||
|
||||
if (event.getNewView() instanceof AdminView) {
|
||||
|
||||
if (subject.isAuthenticated()) {
|
||||
|
||||
if (!permissionChecker.isPermitted("admin")) {
|
||||
Notification.show(
|
||||
"Access denied",
|
||||
"Your are not allowed to access the LibreCCM admin application.",
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
event.getNavigator().navigateTo(LoginView.VIEWNAME);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.cdi.CDIView;
|
||||
import com.vaadin.navigator.View;
|
||||
import com.vaadin.server.VaadinServlet;
|
||||
import com.vaadin.ui.CssLayout;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@CDIView(value = AdminView.VIEWNAME,
|
||||
uis = {AdminUIVaadin.class})
|
||||
public class AdminView extends CustomComponent implements View {
|
||||
|
||||
private static final long serialVersionUID = -2959302663954819489L;
|
||||
|
||||
public static final String VIEWNAME = "admin";
|
||||
|
||||
private final ResourceBundle bundle;
|
||||
|
||||
private final AdminViewController controller;
|
||||
|
||||
private final TabSheet tabSheet;
|
||||
private final TabSheet.Tab tabUsersGroupsRoles;
|
||||
private final UsersGroupsRolesTab usersGroupsRoles;
|
||||
|
||||
private final JpqlConsole jpqlConsole;
|
||||
|
||||
private final ConfigurationTab configurationTab;
|
||||
|
||||
private final SystemInformationTab sysInfoTab;
|
||||
|
||||
@Inject
|
||||
AdminView(final AdminViewController controller) {
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
controller.getGlobalizationHelper().getNegotiatedLocale());
|
||||
|
||||
tabSheet = new TabSheet();
|
||||
|
||||
usersGroupsRoles = new UsersGroupsRolesTab(controller
|
||||
.getUsersGroupsRolesController());
|
||||
tabUsersGroupsRoles = tabSheet
|
||||
.addTab(usersGroupsRoles,
|
||||
bundle.getString("ui.admin.tab.users_groups_roles.title"));
|
||||
|
||||
final ServletContext servletContext = VaadinServlet
|
||||
.getCurrent()
|
||||
.getServletContext();
|
||||
if ("true".equals(servletContext.getInitParameter("ccm.develmode"))) {
|
||||
jpqlConsole = new JpqlConsole(controller.getJpqlConsoleController());
|
||||
tabSheet.addTab(jpqlConsole, "JPQL Console");
|
||||
} else {
|
||||
jpqlConsole = null;
|
||||
}
|
||||
|
||||
final SitesTab sitesTab = new SitesTab(controller);
|
||||
tabSheet.addTab(sitesTab, "Sites");
|
||||
|
||||
final PageModelsTab pageModelsTab = new PageModelsTab(controller);
|
||||
tabSheet.addTab(pageModelsTab, "PageModels");
|
||||
|
||||
configurationTab = new ConfigurationTab();
|
||||
tabSheet.addTab(configurationTab, "Configuration");
|
||||
|
||||
sysInfoTab = new SystemInformationTab(controller);
|
||||
tabSheet.addTab(sysInfoTab, "System Information");
|
||||
|
||||
final CssLayout footer = new CssLayout();
|
||||
footer.setHeight("5em");
|
||||
|
||||
final VerticalLayout viewLayout = new VerticalLayout(new Header(),
|
||||
tabSheet,
|
||||
footer);
|
||||
|
||||
viewLayout.addStyleName("libreccm-main-margin-top");
|
||||
|
||||
super.setCompositionRoot(viewLayout);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Contains injection points for all CDI beans by the AdminView and its
|
||||
* components.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class AdminViewController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4880298854970416968L;
|
||||
|
||||
@Inject
|
||||
private ApplicationTreeDataProvider applicationTreeDataProvider;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager configurationManager;
|
||||
|
||||
@Inject
|
||||
private ConfigurationsTabController confTabController;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private JpqlConsoleController jpqlConsoleController;
|
||||
|
||||
@Inject
|
||||
private PageModelsController pageModelsController;
|
||||
|
||||
@Inject
|
||||
private SitesController sitesController;
|
||||
|
||||
@Inject
|
||||
private UsersGroupsRolesController usersGroupsRolesController;
|
||||
|
||||
protected AdminViewController() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ApplicationTreeDataProvider getApplicationTreeDataProvider() {
|
||||
return applicationTreeDataProvider;
|
||||
}
|
||||
|
||||
public ConfigurationManager getConfigurationManager() {
|
||||
return configurationManager;
|
||||
}
|
||||
|
||||
public ConfigurationsTabController getConfTabController() {
|
||||
return confTabController;
|
||||
}
|
||||
|
||||
protected GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
protected JpqlConsoleController getJpqlConsoleController() {
|
||||
return jpqlConsoleController;
|
||||
}
|
||||
|
||||
protected PageModelsController getPageModelsController() {
|
||||
return pageModelsController;
|
||||
}
|
||||
|
||||
protected SitesController getSitesController() {
|
||||
return sitesController;
|
||||
}
|
||||
|
||||
protected UsersGroupsRolesController getUsersGroupsRolesController() {
|
||||
return usersGroupsRolesController;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider;
|
||||
import com.vaadin.data.provider.HierarchicalQuery;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.web.ApplicationManager;
|
||||
import org.libreccm.web.ApplicationRepository;
|
||||
import org.libreccm.web.ApplicationType;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class ApplicationTreeDataProvider
|
||||
extends AbstractBackEndHierarchicalDataProvider<ApplicationTreeNode, String> {
|
||||
|
||||
private static final long serialVersionUID = 7089444870777208500L;
|
||||
|
||||
@Inject
|
||||
private ApplicationManager applicationManager;
|
||||
|
||||
@Inject
|
||||
private ApplicationRepository applicationRepo;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
private final ApplicationTreeNode rootNode;
|
||||
|
||||
public ApplicationTreeDataProvider() {
|
||||
rootNode = new ApplicationTreeNode();
|
||||
rootNode.setNodeId(ApplicationTreeNode.ROOT);
|
||||
rootNode.setNodeType(ApplicationTreeNodeType.ROOT_NODE);
|
||||
rootNode.setTitle("/");
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
protected Stream<ApplicationTreeNode> fetchChildrenFromBackEnd(
|
||||
final HierarchicalQuery<ApplicationTreeNode, String> query) {
|
||||
|
||||
final ApplicationTreeNode node = query
|
||||
.getParentOptional()
|
||||
.orElse(rootNode);
|
||||
|
||||
switch (node.getNodeType()) {
|
||||
case APPLICATION_TYPE_NODE:
|
||||
return fetchApplicationInstances(node);
|
||||
case ROOT_NODE:
|
||||
return fetchApplicationTypes();
|
||||
default:
|
||||
throw new IllegalArgumentException(String
|
||||
.format("Invalid value \"%s\" for nodeType.",
|
||||
node.getNodeType()));
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<ApplicationTreeNode> fetchApplicationTypes() {
|
||||
|
||||
return applicationManager
|
||||
.getApplicationTypes()
|
||||
.values()
|
||||
.stream()
|
||||
.map(this::buildApplicationTreeNode)
|
||||
.sorted();
|
||||
}
|
||||
|
||||
private ApplicationTreeNode buildApplicationTreeNode(
|
||||
final ApplicationType type) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(type.descBundle());
|
||||
|
||||
final String title = textsUtil.getText(type.titleKey());
|
||||
|
||||
final ApplicationTreeNode node = new ApplicationTreeNode();
|
||||
node.setTitle(title);
|
||||
|
||||
if (type.singleton()) {
|
||||
node.setNodeType(ApplicationTreeNodeType.SINGLETON_APPLICATION_NODE);
|
||||
|
||||
final List<CcmApplication> instances = applicationRepo
|
||||
.findByType(type.name());
|
||||
|
||||
if (instances.size() > 1) {
|
||||
throw new UnexpectedErrorException(String
|
||||
.format("Application type \"%s\" is marked as singleton but"
|
||||
+ "there are multiple instances.",
|
||||
type.name()));
|
||||
}
|
||||
|
||||
final CcmApplication instance = instances.get(0);
|
||||
node.setNodeId(instance.getUuid());
|
||||
} else {
|
||||
node.setNodeType(ApplicationTreeNodeType.APPLICATION_TYPE_NODE);
|
||||
node.setNodeId(type.name());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private Stream<ApplicationTreeNode> fetchApplicationInstances(
|
||||
final ApplicationTreeNode parent) {
|
||||
|
||||
if (parent.getNodeType()
|
||||
!= ApplicationTreeNodeType.APPLICATION_TYPE_NODE) {
|
||||
throw new IllegalArgumentException("Provided parent node is not a "
|
||||
+ ApplicationTreeNodeType.APPLICATION_TYPE_NODE);
|
||||
}
|
||||
|
||||
final String type = parent.getNodeId();
|
||||
|
||||
return applicationRepo
|
||||
.findByType(type)
|
||||
.stream()
|
||||
.map(this::buildApplicationTreeNode)
|
||||
.sorted();
|
||||
}
|
||||
|
||||
private ApplicationTreeNode buildApplicationTreeNode(
|
||||
final CcmApplication application) {
|
||||
|
||||
final ApplicationTreeNode node = new ApplicationTreeNode();
|
||||
|
||||
node.setNodeId(application.getUuid());
|
||||
node.setNodeType(ApplicationTreeNodeType.APPLICATION_NODE);
|
||||
final String title;
|
||||
if (globalizationHelper
|
||||
.getValueFromLocalizedString(application.getTitle()) == null
|
||||
|| globalizationHelper
|
||||
.getValueFromLocalizedString(application.getTitle()).isEmpty()) {
|
||||
|
||||
title = application.getPrimaryUrl();
|
||||
} else {
|
||||
title =globalizationHelper
|
||||
.getValueFromLocalizedString(application.getTitle());
|
||||
}
|
||||
node.setTitle(title);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(
|
||||
final HierarchicalQuery<ApplicationTreeNode, String> query) {
|
||||
|
||||
return (int) fetchChildrenFromBackEnd(query).count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(final ApplicationTreeNode item) {
|
||||
|
||||
switch (item.getNodeType()) {
|
||||
case APPLICATION_NODE:
|
||||
return false;
|
||||
case APPLICATION_TYPE_NODE:
|
||||
return true;
|
||||
case ROOT_NODE:
|
||||
return true;
|
||||
case SINGLETON_APPLICATION_NODE:
|
||||
return false;
|
||||
default:
|
||||
throw new IllegalArgumentException(String
|
||||
.format("Invalid value \"%s\" for nodeType.",
|
||||
item.getNodeType()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class encapsulating the information displayed in a application tree.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class ApplicationTreeNode implements Serializable,
|
||||
Comparable<ApplicationTreeNode> {
|
||||
|
||||
private static final long serialVersionUID = -3123536103514717506L;
|
||||
|
||||
protected static final String ROOT = "@ROOT@";
|
||||
|
||||
|
||||
/**
|
||||
* ID of the node. If the node is the root node, the ID will be
|
||||
* {@link #ROOT}. If the node is an application type node the ID will be the
|
||||
* name of the application type class. If it is an application (instance)
|
||||
* node, the name will be the UUID of the instance.
|
||||
*/
|
||||
private String nodeId;
|
||||
|
||||
/**
|
||||
* Type of the the node.
|
||||
*/
|
||||
private ApplicationTreeNodeType nodeType;
|
||||
|
||||
/**
|
||||
* The title of the node.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public void setNodeId(final String nodeId) {
|
||||
this.nodeId = nodeId;
|
||||
}
|
||||
|
||||
public ApplicationTreeNodeType getNodeType() {
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setNodeType(final ApplicationTreeNodeType nodeType) {
|
||||
this.nodeType = nodeType;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(final String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final ApplicationTreeNode other) {
|
||||
|
||||
int result = title.compareTo(other.getTitle());
|
||||
if (result == 0) {
|
||||
result = nodeType.compareTo(other.getNodeType());
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
result = nodeId.compareTo(other.getNodeId());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 53 * hash + Objects.hashCode(this.nodeId);
|
||||
hash = 53 * hash + Objects.hashCode(this.nodeType);
|
||||
hash = 53 * hash + Objects.hashCode(this.title);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof ApplicationTreeNode)) {
|
||||
return false;
|
||||
}
|
||||
final ApplicationTreeNode other = (ApplicationTreeNode) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.nodeId, other.getNodeId())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(this.title, other.getTitle())) {
|
||||
return false;
|
||||
}
|
||||
return this.nodeType == other.getNodeType();
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof ApplicationTreeNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "nodeId = \"%s\", "
|
||||
+ "nodeType = \"%s\", "
|
||||
+ "title = \"%s\"%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
nodeId,
|
||||
nodeType,
|
||||
title,
|
||||
data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
/**
|
||||
* Enum of the possible types of a node.
|
||||
*/
|
||||
enum ApplicationTreeNodeType {
|
||||
ROOT_NODE,
|
||||
APPLICATION_TYPE_NODE,
|
||||
APPLICATION_NODE,
|
||||
SINGLETON_APPLICATION_NODE
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ConfigurationSettingsGridRowData {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.data.provider.CallbackDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.*;
|
||||
import org.libreccm.configuration.ConfigurationInfo;
|
||||
import org.libreccm.configuration.SettingInfo;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class ConfigurationSettingsWindow extends Window {
|
||||
|
||||
private static final long serialVersionUID = 2706661932737914254L;
|
||||
|
||||
private final String COL_SETTING_LABEL = "setting_label";
|
||||
private final String COL_SETTING_EDITOR = "setting_editor";
|
||||
|
||||
private final Class<?> configurationClass;
|
||||
private final ConfigurationInfo configurationInfo;
|
||||
private final ConfigurationTab configurationTab;
|
||||
private Object configuration;
|
||||
|
||||
private final Button saveButton;
|
||||
|
||||
public ConfigurationSettingsWindow(final Class<?> configurationClass,
|
||||
final ConfigurationInfo configurationInfo,
|
||||
final ConfigurationTab configurationTab) {
|
||||
|
||||
super();
|
||||
|
||||
this.configurationClass = configurationClass;
|
||||
this.configurationInfo = configurationInfo;
|
||||
this.configurationTab = configurationTab;
|
||||
|
||||
final Locale locale = configurationTab
|
||||
.getGlobalizationHelper()
|
||||
.getNegotiatedLocale();
|
||||
|
||||
final Grid<SettingInfo> settingsGrid = new Grid<>(
|
||||
new CallbackDataProvider<SettingInfo, String>(
|
||||
query -> fetchSettingInfos(configurationClass,
|
||||
configurationTab,
|
||||
query),
|
||||
query -> countSettings(configurationClass,
|
||||
configurationTab,
|
||||
query)));
|
||||
settingsGrid
|
||||
.addColumn(settingInfo -> settingInfo.getLabel(locale))
|
||||
.setId(COL_SETTING_LABEL)
|
||||
.setCaption("Setting");
|
||||
settingsGrid
|
||||
.addComponentColumn(settingInfo -> createSettingEditor(settingInfo))
|
||||
.setId(COL_SETTING_EDITOR)
|
||||
.setCaption("Edit");
|
||||
|
||||
settingsGrid.setWidth("100%");
|
||||
|
||||
super.setCaption(
|
||||
String.format("Edit setting of configuration \"%s\"",
|
||||
configurationInfo
|
||||
.getTitle(locale,
|
||||
configurationTab.getDefaultLocale())));
|
||||
|
||||
saveButton = new Button("Save");
|
||||
saveButton.addClickListener(event -> {
|
||||
configurationTab
|
||||
.getConfigurationManager()
|
||||
.saveConfiguration(configuration);
|
||||
close();
|
||||
});
|
||||
saveButton.setEnabled(false);
|
||||
final Button cancelButton = new Button("Cancel");
|
||||
cancelButton.addClickListener(event -> close());
|
||||
|
||||
super.setContent(new VerticalLayout(
|
||||
new HorizontalLayout(saveButton, cancelButton),
|
||||
settingsGrid));
|
||||
}
|
||||
|
||||
private Stream<SettingInfo> fetchSettingInfos(
|
||||
final Class<?> configurationClass,
|
||||
final ConfigurationTab configurationTab,
|
||||
final Query<SettingInfo, String> query) {
|
||||
|
||||
final int fromIndex;
|
||||
final int toIndex;
|
||||
final int size = countSettings(configurationClass,
|
||||
configurationTab,
|
||||
query);
|
||||
if (query.getOffset() > size - 1) {
|
||||
fromIndex = size -1;
|
||||
} else {
|
||||
fromIndex = query.getOffset();
|
||||
}
|
||||
|
||||
if (query.getOffset() + query.getLimit() > size) {
|
||||
toIndex = size;
|
||||
} else {
|
||||
toIndex = query.getOffset() + query.getLimit();
|
||||
}
|
||||
|
||||
|
||||
return configurationTab
|
||||
.getSettingManager()
|
||||
.getAllSettings(configurationClass)
|
||||
.subList(fromIndex, toIndex)
|
||||
.stream()
|
||||
.map(settingName -> {
|
||||
return configurationTab
|
||||
.getSettingManager()
|
||||
.getSettingInfo(configurationClass, settingName);
|
||||
});
|
||||
}
|
||||
|
||||
private int countSettings(final Class<?> configurationClass,
|
||||
final ConfigurationTab configurationTab,
|
||||
final Query<SettingInfo, String> query) {
|
||||
|
||||
return configurationTab
|
||||
.getSettingManager()
|
||||
.getAllSettings(configurationClass)
|
||||
.size();
|
||||
}
|
||||
|
||||
private Component createSettingEditor(final SettingInfo settingInfo) {
|
||||
|
||||
final String type = settingInfo.getValueType();
|
||||
final String name = settingInfo.getName();
|
||||
|
||||
if (Boolean.class.getName().equals(type)
|
||||
|| Boolean.TYPE.getName().equals(type)) {
|
||||
|
||||
final CheckBox checkBox = new CheckBox();
|
||||
checkBox.addValueChangeListener(event -> {
|
||||
updateSettingValue(name, event.getValue());
|
||||
});
|
||||
return checkBox;
|
||||
} else if (BigDecimal.class.getName().equals(type)) {
|
||||
|
||||
final TextField textField = new TextField();
|
||||
textField.addValueChangeListener(event -> {
|
||||
final String value = event.getValue();
|
||||
if (value.matches("\\d*")) {
|
||||
updateSettingValue(name, new BigDecimal(value));
|
||||
} else {
|
||||
textField.setComponentError(new UserError(
|
||||
"The value is not numeric"));
|
||||
}
|
||||
});
|
||||
return textField;
|
||||
} else if (Double.class.getName().equals(type)
|
||||
|| Double.TYPE.getName().equals(type)) {
|
||||
|
||||
final TextField textField = new TextField();
|
||||
textField.addValueChangeListener(event -> {
|
||||
try {
|
||||
final Double value = Double.parseDouble(event.getValue());
|
||||
updateSettingValue(name, value);
|
||||
} catch (NumberFormatException ex) {
|
||||
textField.setComponentError(new UserError(
|
||||
"The value is not a double value."));
|
||||
}
|
||||
});
|
||||
return textField;
|
||||
} else if (Set.class.getName().equals(type)) {
|
||||
|
||||
return new Label("Not supported yet.");
|
||||
|
||||
} else if (LocalizedString.class.getName().equals(type)) {
|
||||
|
||||
return new Label("Not supported yet.");
|
||||
|
||||
} else if (Long.class.getName().equals(type)
|
||||
|| Long.TYPE.getName().equals(type)) {
|
||||
|
||||
final TextField textField = new TextField();
|
||||
textField.addValueChangeListener(event -> {
|
||||
try {
|
||||
final Long value = Long.parseLong(event.getValue());
|
||||
updateSettingValue(name, value);
|
||||
} catch (NumberFormatException ex) {
|
||||
textField.setComponentError(new UserError(
|
||||
"The value is not a double value."));
|
||||
}
|
||||
});
|
||||
return textField;
|
||||
|
||||
} else if (List.class.getName().equals(type)) {
|
||||
|
||||
return new Label("Not supported yet.");
|
||||
|
||||
} else if (String.class.getName().equals(type)) {
|
||||
|
||||
final TextField textField = new TextField();
|
||||
textField.addValueChangeListener(event -> {
|
||||
updateSettingValue(name, event.getValue());
|
||||
});
|
||||
return textField;
|
||||
|
||||
} else {
|
||||
return new Label("Unsupported value type");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSettingValue(final String settingName,
|
||||
final Object value) {
|
||||
|
||||
if (configuration == null) {
|
||||
//We can't do that in the constructor because this values are
|
||||
//provided by CDI in other classes. Therefore they might be
|
||||
//not available when the constructors runs.
|
||||
configuration = configurationTab
|
||||
.getConfigurationManager()
|
||||
.findConfiguration(configurationClass);
|
||||
saveButton.setEnabled(true);
|
||||
}
|
||||
|
||||
try {
|
||||
final Field field = configurationClass.getField(settingName);
|
||||
field.setAccessible(true);
|
||||
field.set(configuration, value);
|
||||
} catch (IllegalAccessException | NoSuchFieldException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.configuration.SettingManager;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ConfigurationTab extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = 7642627611731762410L;
|
||||
|
||||
private static final String COL_CONF_TITLE = "title";
|
||||
private static final String COL_CONF_CLASS = "configuration_class";
|
||||
private static final String COL_CONF_DESC = "description";
|
||||
|
||||
private ConfigurationsTabController controller;
|
||||
|
||||
private final Grid<ConfigurationsGridRowData> configurationsGrid;
|
||||
|
||||
public ConfigurationTab() {
|
||||
|
||||
super();
|
||||
configurationsGrid = new Grid<>();
|
||||
|
||||
configurationsGrid.addComponentColumn(rowData -> {
|
||||
final Button button = new Button(
|
||||
rowData.getTitle(),
|
||||
event -> {
|
||||
final ConfigurationSettingsWindow window
|
||||
= new ConfigurationSettingsWindow(
|
||||
rowData.getConfigurationClass(),
|
||||
rowData.getConfigurationInfo(),
|
||||
this);
|
||||
window.setWidth("70%");
|
||||
window.center();
|
||||
UI.getCurrent().addWindow(window);
|
||||
});
|
||||
button.setStyleName(ValoTheme.BUTTON_LINK);
|
||||
|
||||
return button;
|
||||
})
|
||||
.setId(COL_CONF_TITLE);
|
||||
|
||||
configurationsGrid.addColumn(
|
||||
ConfigurationsGridRowData::getName)
|
||||
.setId(COL_CONF_CLASS)
|
||||
.setCaption("Configuration class");
|
||||
|
||||
configurationsGrid.addColumn(
|
||||
ConfigurationsGridRowData::getDescription)
|
||||
.setCaption(COL_CONF_DESC)
|
||||
.setCaption("Description");
|
||||
|
||||
configurationsGrid.setWidth("100%");
|
||||
|
||||
super.setCompositionRoot(configurationsGrid);
|
||||
|
||||
}
|
||||
|
||||
protected void init(final ConfigurationsTabController controller) {
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
configurationsGrid
|
||||
.setDataProvider(controller.getConfigurationsTableDataProvider());
|
||||
}
|
||||
|
||||
protected GlobalizationHelper getGlobalizationHelper() {
|
||||
return controller.getGlobalizationHelper();
|
||||
}
|
||||
|
||||
protected Locale getDefaultLocale() {
|
||||
return controller.getDefaultLocale();
|
||||
}
|
||||
|
||||
protected ConfigurationManager getConfigurationManager() {
|
||||
return controller.getConfigurationManager();
|
||||
}
|
||||
|
||||
protected SettingManager getSettingManager() {
|
||||
return controller.getSettingManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.configuration.ConfigurationInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class ConfigurationsGridRowData {
|
||||
|
||||
private Class<?> configurationClass;
|
||||
private ConfigurationInfo configurationInfo;
|
||||
private String name;
|
||||
private String title;
|
||||
private String description;
|
||||
|
||||
public ConfigurationsGridRowData() {
|
||||
}
|
||||
|
||||
public Class<?> getConfigurationClass() {
|
||||
return configurationClass;
|
||||
}
|
||||
|
||||
public void setConfigurationClass(
|
||||
Class<?> configurationClass) {
|
||||
this.configurationClass = configurationClass;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
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 ConfigurationInfo getConfigurationInfo() {
|
||||
return configurationInfo;
|
||||
}
|
||||
|
||||
public void setConfigurationInfo(final ConfigurationInfo configurationInfo) {
|
||||
this.configurationInfo = configurationInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.configuration.SettingManager;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class ConfigurationsTabController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5492006905558481631L;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
@Inject
|
||||
private ConfigurationsTableDataProvider configurationsTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager configurationManager;
|
||||
|
||||
@Inject
|
||||
private SettingManager settingManager;
|
||||
|
||||
protected GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
protected Locale getDefaultLocale() {
|
||||
return confManager
|
||||
.findConfiguration(KernelConfig.class)
|
||||
.getDefaultLocale();
|
||||
}
|
||||
|
||||
protected ConfigurationsTableDataProvider getConfigurationsTableDataProvider() {
|
||||
return configurationsTableDataProvider;
|
||||
}
|
||||
|
||||
protected ConfigurationManager getConfigurationManager() {
|
||||
return configurationManager;
|
||||
}
|
||||
|
||||
protected SettingManager getSettingManager() {
|
||||
return settingManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.configuration.ConfigurationInfo;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class ConfigurationsTableDataProvider
|
||||
extends AbstractDataProvider<ConfigurationsGridRowData, String> {
|
||||
|
||||
private static final long serialVersionUID = -7001151229931864885L;
|
||||
|
||||
private String filter;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<ConfigurationsGridRowData, String> query) {
|
||||
|
||||
final Locale defaultLocale = confManager
|
||||
.findConfiguration(KernelConfig.class)
|
||||
.getDefaultLocale();
|
||||
|
||||
if (filter == null || filter.trim().isEmpty()) {
|
||||
return confManager.findAllConfigurations().size();
|
||||
} else {
|
||||
return (int) confManager
|
||||
.findAllConfigurations()
|
||||
.stream()
|
||||
.filter(conf -> {
|
||||
final ConfigurationInfo info = confManager
|
||||
.getConfigurationInfo(conf);
|
||||
if (filter == null || filter.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
return info
|
||||
.getTitle(globalizationHelper.getNegotiatedLocale(),
|
||||
defaultLocale)
|
||||
.startsWith(filter);
|
||||
}
|
||||
})
|
||||
.count();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ConfigurationsGridRowData> fetch(
|
||||
final Query<ConfigurationsGridRowData, String> query) {
|
||||
|
||||
final int fromIndex;
|
||||
final int toIndex;
|
||||
final int size = size(query);
|
||||
if (query.getOffset() > size - 1) {
|
||||
fromIndex = size - 1;
|
||||
} else {
|
||||
fromIndex = query.getOffset();
|
||||
}
|
||||
|
||||
if ((query.getOffset() + query.getLimit()) > size) {
|
||||
toIndex = size;
|
||||
} else {
|
||||
toIndex = query.getOffset() + query.getLimit();
|
||||
}
|
||||
|
||||
if (filter == null || filter.trim().isEmpty()) {
|
||||
return confManager
|
||||
.findAllConfigurations()
|
||||
.stream()
|
||||
.map(configurationClass -> createRowData(configurationClass))
|
||||
.sorted((rowData1, rowData2) -> {
|
||||
return rowData1
|
||||
.getConfigurationClass()
|
||||
.getSimpleName()
|
||||
.compareTo(rowData2.getConfigurationClass()
|
||||
.getSimpleName());
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
.subList(fromIndex, toIndex)
|
||||
.stream();
|
||||
} else {
|
||||
return confManager
|
||||
.findAllConfigurations()
|
||||
.stream()
|
||||
.map(configurationClass -> createRowData(configurationClass))
|
||||
.filter(rowData -> {
|
||||
if (filter == null || filter.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
return rowData
|
||||
.getTitle()
|
||||
.startsWith(filter);
|
||||
}
|
||||
})
|
||||
.sorted((rowData1, rowData2) -> {
|
||||
return rowData1
|
||||
.getConfigurationClass()
|
||||
.getSimpleName()
|
||||
.compareTo(rowData2.getConfigurationClass()
|
||||
.getSimpleName());
|
||||
})
|
||||
.collect(Collectors.toList())
|
||||
.subList(fromIndex, toIndex)
|
||||
.stream();
|
||||
}
|
||||
}
|
||||
|
||||
public void setFilter(final String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
private ConfigurationsGridRowData createRowData(
|
||||
final Class<?> configurationClass) {
|
||||
|
||||
final ConfigurationInfo info = confManager
|
||||
.getConfigurationInfo(configurationClass);
|
||||
|
||||
final Locale defaultLocale = confManager
|
||||
.findConfiguration(KernelConfig.class)
|
||||
.getDefaultLocale();
|
||||
|
||||
final ConfigurationsGridRowData rowData
|
||||
= new ConfigurationsGridRowData();
|
||||
rowData.setConfigurationClass(configurationClass);
|
||||
rowData.setName(info.getName());
|
||||
rowData.setTitle(info
|
||||
.getTitle(globalizationHelper.getNegotiatedLocale(),
|
||||
defaultLocale));
|
||||
rowData.setDescription(info
|
||||
.getDescription(globalizationHelper.getNegotiatedLocale()));
|
||||
rowData.setConfigurationInfo(info);
|
||||
|
||||
return rowData;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
import com.vaadin.ui.*;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ConfirmDiscardDialog extends Window {
|
||||
|
||||
private static final long serialVersionUID = 7270363517221672796L;
|
||||
|
||||
public ConfirmDiscardDialog(final Window window,
|
||||
final String message) {
|
||||
|
||||
if (window == this) {
|
||||
throw new IllegalArgumentException("ConfirmDiscardDialog can't be "
|
||||
+ "used with itself.");
|
||||
}
|
||||
|
||||
setCaption(message);
|
||||
|
||||
final Label label = new Label(message);
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final Button yesButton = new Button(bundle.getString("ui.admin.yes"));
|
||||
yesButton.addClickListener(event -> {
|
||||
close();
|
||||
UI.getCurrent().removeWindow(window);
|
||||
});
|
||||
|
||||
final Button noButton = new Button(bundle.getString("ui.admin.no"));
|
||||
noButton.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttonsLayout = new HorizontalLayout(yesButton,
|
||||
noButton);
|
||||
final VerticalLayout layout = new VerticalLayout(label,
|
||||
buttonsLayout);
|
||||
|
||||
setContent(layout);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,354 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class GroupDetails extends Window {
|
||||
|
||||
private static final long serialVersionUID = 4252189590984878037L;
|
||||
|
||||
private static final String COL_USER_NAME = "username";
|
||||
private static final String COL_GIVEN_NAME = "given_name";
|
||||
private static final String COL_FAMILY_NAME = "family_name";
|
||||
private static final String COL_EMAIL = "email";
|
||||
private static final String COL_REMOVE = "remove";
|
||||
|
||||
private static final String COL_ROLE_NAME = "role_name";
|
||||
private static final String COL_ROLE_REMOVE = "remove";
|
||||
|
||||
private final Group group;
|
||||
private final GroupsController controller;
|
||||
|
||||
private boolean dataHasChanged = false;
|
||||
|
||||
private Label groupNameDisplay;
|
||||
private TextField groupNameField;
|
||||
private Button editButton;
|
||||
private HorizontalLayout saveCancelButtons;
|
||||
|
||||
protected GroupDetails(final Group group,
|
||||
final GroupsController controller) {
|
||||
|
||||
super(String.format("Edit group %s", group.getName()));
|
||||
|
||||
this.group = group;
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final GroupDetails.DataHasChangedListener dataHasChangedListener
|
||||
= new GroupDetails.DataHasChangedListener();
|
||||
|
||||
groupNameDisplay = new Label();
|
||||
groupNameDisplay.setCaption(bundle
|
||||
.getString("ui.admin.group_edit.groupname.label"));
|
||||
|
||||
groupNameField = new TextField(bundle
|
||||
.getString("ui.admin.group_edit.groupname.label"));
|
||||
groupNameField.setRequiredIndicatorVisible(true);
|
||||
|
||||
editButton = new Button("ui.admin.group.edit");
|
||||
editButton.addClickListener(event -> {
|
||||
groupNameDisplay.setVisible(false);
|
||||
groupNameField.setVisible(true);
|
||||
editButton.setVisible(false);
|
||||
saveCancelButtons.setVisible(true);
|
||||
});
|
||||
|
||||
final Button submit = new Button();
|
||||
submit.setCaption(bundle.getString("ui.admin.save"));
|
||||
submit.addClickListener(event -> saveGroup());
|
||||
|
||||
final Button cancel = new Button(bundle.getString("ui.admin.cancel"));
|
||||
cancel.addClickListener(event -> {
|
||||
groupNameField.setValue(group.getName());
|
||||
groupNameField.setVisible(false);
|
||||
saveCancelButtons.setVisible(false);
|
||||
editButton.setVisible(true);
|
||||
groupNameDisplay.setVisible(true);
|
||||
});
|
||||
|
||||
saveCancelButtons = new HorizontalLayout(submit, cancel);
|
||||
|
||||
final FormLayout formLayout = new FormLayout(groupNameDisplay,
|
||||
groupNameField);
|
||||
groupNameField.setVisible(false);
|
||||
|
||||
groupNameField.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout,
|
||||
editButton,
|
||||
saveCancelButtons);
|
||||
saveCancelButtons.setVisible(false);
|
||||
|
||||
final Panel propertiesPanel = new Panel(layout);
|
||||
propertiesPanel.setCaption(bundle
|
||||
.getString("ui.admin.group_details.edit"));
|
||||
|
||||
groupNameDisplay.setValue(group.getName());
|
||||
groupNameField.setValue(group.getName());
|
||||
|
||||
dataHasChanged = false;
|
||||
|
||||
final GroupMembersController membersController = controller
|
||||
.getMembersController();
|
||||
|
||||
final Grid<User> membersGrid = new Grid<>();
|
||||
membersGrid.addColumn(User::getName)
|
||||
.setId(COL_USER_NAME)
|
||||
.setCaption("User Name");
|
||||
membersGrid.addColumn(User::getGivenName)
|
||||
.setId(COL_GIVEN_NAME)
|
||||
.setCaption("Given name");
|
||||
membersGrid.addColumn(User::getFamilyName)
|
||||
.setId(COL_FAMILY_NAME)
|
||||
.setCaption("Family name");
|
||||
membersGrid
|
||||
.addColumn(user -> user.getPrimaryEmailAddress().getAddress())
|
||||
.setId(COL_EMAIL)
|
||||
.setCaption("E-Mail");
|
||||
membersGrid.addComponentColumn(user -> {
|
||||
final Button removeButton = new Button(
|
||||
bundle.getString("ui.groups.members.remove"),
|
||||
VaadinIcons.CLOSE_CIRCLE_O);
|
||||
removeButton.addClickListener(event -> {
|
||||
membersController.removeMemberFromGroup(user,
|
||||
group);
|
||||
membersGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
removeButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return removeButton;
|
||||
})
|
||||
.setId(COL_REMOVE);
|
||||
|
||||
membersGrid.setWidth("100%");
|
||||
|
||||
final UserRepository userRepo = controller.getUserRepository();
|
||||
|
||||
final HeaderRow membersGridHeader = membersGrid.prependHeaderRow();
|
||||
final Button addMemberButton = new Button("Add member");
|
||||
addMemberButton.setIcon(VaadinIcons.PLUS);
|
||||
addMemberButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
addMemberButton.addClickListener(event -> {
|
||||
final UserSelector userSelector = new UserSelector(
|
||||
"Select users to add to group",
|
||||
"Add selected users to group",
|
||||
controller.getUserSelectorDataProvider(),
|
||||
userRepo.findByGroup(group),
|
||||
(selectedUsers -> {
|
||||
selectedUsers.forEach(user -> {
|
||||
membersController
|
||||
.addMembersToGroup(selectedUsers, group);
|
||||
membersGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
}));
|
||||
userSelector.addCloseListener(closeEvent -> {
|
||||
membersGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
userSelector.center();
|
||||
userSelector.setWidth("80%");
|
||||
UI.getCurrent().addWindow(userSelector);
|
||||
});
|
||||
final HeaderCell membersGridHeaderCell = membersGridHeader
|
||||
.join(COL_USER_NAME,
|
||||
COL_GIVEN_NAME,
|
||||
COL_FAMILY_NAME,
|
||||
COL_EMAIL,
|
||||
COL_REMOVE);
|
||||
membersGridHeaderCell
|
||||
.setComponent(new HorizontalLayout(addMemberButton));
|
||||
|
||||
final GroupMembersTableDataProvider usersDataProvider = controller
|
||||
.getMembersTableDataProvider();
|
||||
usersDataProvider.setGroup(group);
|
||||
membersGrid.setDataProvider(usersDataProvider);
|
||||
|
||||
final GroupRolesController rolesController = controller
|
||||
.getRolesController();
|
||||
final Grid<Role> rolesGrid = new Grid<>();
|
||||
rolesGrid
|
||||
.addColumn(Role::getName)
|
||||
.setId(COL_ROLE_NAME)
|
||||
.setCaption("Role Name");
|
||||
rolesGrid.addComponentColumn(role -> {
|
||||
final Button removeButton = new Button(
|
||||
bundle.getString("ui.groups.roles.remove"),
|
||||
VaadinIcons.CLOSE_CIRCLE_O);
|
||||
removeButton.addClickListener(event -> {
|
||||
rolesController.removeRoleFromGroup(role, group);
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
removeButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return removeButton;
|
||||
})
|
||||
.setId(COL_ROLE_REMOVE);
|
||||
|
||||
rolesGrid.setWidth("100%");
|
||||
|
||||
final RoleRepository roleRepo = controller.getRoleRepository();
|
||||
|
||||
final HeaderRow rolesGridHeader = rolesGrid.prependHeaderRow();
|
||||
final Button addRoleButton = new Button("Add role");
|
||||
addRoleButton.setIcon(VaadinIcons.PLUS);
|
||||
addRoleButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
addRoleButton.addClickListener(event -> {
|
||||
final RoleSelector roleSelector = new RoleSelector(
|
||||
"Select role(s) to add to group",
|
||||
"Add selected role(s) to group",
|
||||
controller.getRoleSelectorDataProvider(),
|
||||
roleRepo.findByParty(group),
|
||||
(selectedRoles -> {
|
||||
selectedRoles.forEach(role -> {
|
||||
rolesController.assignRoleToGroup(role, group);
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
}));
|
||||
roleSelector.addCloseListener(closeEvent -> {
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
roleSelector.center();
|
||||
roleSelector.setWidth("80%");
|
||||
UI.getCurrent().addWindow(roleSelector);
|
||||
});
|
||||
final HeaderCell rolesGridHeaderCell = rolesGridHeader
|
||||
.join(COL_ROLE_NAME,
|
||||
COL_ROLE_REMOVE);
|
||||
rolesGridHeaderCell
|
||||
.setComponent(new HorizontalLayout(addRoleButton));
|
||||
|
||||
final GroupRolesTableDataProvider rolesDataProvider = controller
|
||||
.getRolesTableDataProvider();
|
||||
rolesDataProvider.setGroup(group);
|
||||
rolesGrid.setDataProvider(rolesDataProvider);
|
||||
|
||||
final TabSheet tabs = new TabSheet();
|
||||
tabs.addTab(membersGrid, "Members");
|
||||
tabs.addTab(rolesGrid, "Roles");
|
||||
|
||||
final VerticalLayout windowLayout = new VerticalLayout(propertiesPanel,
|
||||
tabs);
|
||||
|
||||
setContent(windowLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
if (dataHasChanged) {
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final ConfirmDiscardDialog dialog = new ConfirmDiscardDialog(
|
||||
this,
|
||||
bundle.getString("ui.admin.group_edit.discard_confirm"));
|
||||
dialog.setModal(true);
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
} else {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveGroup() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
if (groupNameField.getValue() == null
|
||||
|| groupNameField.getValue().trim().isEmpty()) {
|
||||
|
||||
groupNameField.setComponentError(new UserError(
|
||||
bundle.getString("ui.admin.group_edit.groupname.error.notempty")));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String notificationText;
|
||||
group.setName(groupNameField.getValue());
|
||||
notificationText = String.format("Saved changes to group %s",
|
||||
group.getName());
|
||||
|
||||
controller.getGroupRepository().save(group);
|
||||
|
||||
dataHasChanged = false;
|
||||
close();
|
||||
new Notification(notificationText, Notification.Type.TRAY_NOTIFICATION)
|
||||
.show(Page.getCurrent());
|
||||
}
|
||||
|
||||
private class DataHasChangedListener
|
||||
implements HasValue.ValueChangeListener<String> {
|
||||
|
||||
private static final long serialVersionUID = -1410903365203533072L;
|
||||
|
||||
@Override
|
||||
public void valueChange(final HasValue.ValueChangeEvent<String> event) {
|
||||
dataHasChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class GroupEditor extends Window {
|
||||
|
||||
private static final long serialVersionUID = -5834095844674226692L;
|
||||
|
||||
private final Group group;
|
||||
private final GroupRepository groupRepo;
|
||||
|
||||
private boolean dataHasChanged = false;
|
||||
|
||||
private TextField groupName;
|
||||
|
||||
protected GroupEditor(final GroupRepository groupRepo) {
|
||||
|
||||
super("Create new group");
|
||||
|
||||
group = null;
|
||||
this.groupRepo = groupRepo;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public GroupEditor(final Group group,
|
||||
final GroupRepository groupRepo) {
|
||||
|
||||
super(String.format("Edit group %s", group.getName()));
|
||||
|
||||
this.group = group;
|
||||
this.groupRepo = groupRepo;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final DataHasChangedListener dataHasChangedListener
|
||||
= new DataHasChangedListener();
|
||||
|
||||
groupName = new TextField(bundle
|
||||
.getString("ui.admin.group_edit.groupname.label"));
|
||||
groupName.setRequiredIndicatorVisible(true);
|
||||
groupName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
final Button submit = new Button();
|
||||
if (group == null) {
|
||||
submit.setCaption(bundle
|
||||
.getString("ui.admin.group.createpanel.header"));
|
||||
} else {
|
||||
submit.setCaption(bundle.getString("ui.admin.save"));
|
||||
}
|
||||
submit.addClickListener(event -> saveGroup());
|
||||
|
||||
final Button cancel = new Button(bundle.getString("ui.admin.cancel"));
|
||||
cancel.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttons = new HorizontalLayout(submit, cancel);
|
||||
|
||||
final FormLayout formLayout = new FormLayout(groupName);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout, buttons);
|
||||
|
||||
final Panel panel = new Panel(layout);
|
||||
if (group == null) {
|
||||
panel.setCaption(bundle
|
||||
.getString("ui.admin.group.createpanel.header"));
|
||||
} else {
|
||||
panel.setCaption(bundle
|
||||
.getString("ui.admin.group_details.edit"));
|
||||
}
|
||||
|
||||
if (group != null) {
|
||||
groupName.setValue(group.getName());
|
||||
}
|
||||
|
||||
setContent(panel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
if (dataHasChanged) {
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final ConfirmDiscardDialog dialog = new ConfirmDiscardDialog(
|
||||
this,
|
||||
bundle.getString("ui.admin.group_edit.discard_confirm"));
|
||||
dialog.setModal(true);
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
} else {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveGroup() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
if (groupName.getValue() == null
|
||||
|| groupName.getValue().trim().isEmpty()) {
|
||||
|
||||
groupName.setComponentError(new UserError(
|
||||
bundle.getString("ui.admin.group_edit.groupname.error.notempty")));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Group currentGroup;
|
||||
final String notificationText;
|
||||
if (group == null) {
|
||||
|
||||
currentGroup = new Group();
|
||||
currentGroup.setName(groupName.getValue());
|
||||
notificationText = String.format("Created new group %s",
|
||||
currentGroup.getName());
|
||||
} else {
|
||||
currentGroup = group;
|
||||
group.setName(groupName.getValue());
|
||||
notificationText = String.format("Saved changes to group %s",
|
||||
currentGroup.getName());
|
||||
}
|
||||
|
||||
groupRepo.save(currentGroup);
|
||||
|
||||
dataHasChanged = false;
|
||||
close();
|
||||
new Notification(notificationText, Notification.Type.TRAY_NOTIFICATION)
|
||||
.show(Page.getCurrent());
|
||||
}
|
||||
|
||||
private class DataHasChangedListener
|
||||
implements HasValue.ValueChangeListener<String> {
|
||||
|
||||
private static final long serialVersionUID = -1410903365203533072L;
|
||||
|
||||
@Override
|
||||
public void valueChange(final HasValue.ValueChangeEvent<String> event) {
|
||||
dataHasChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupManager;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class GroupMembersController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 9206311321172059643L;
|
||||
|
||||
@Inject
|
||||
private UserRepository userRepo;
|
||||
|
||||
@Inject
|
||||
private GroupRepository groupRepo;
|
||||
|
||||
@Inject
|
||||
private GroupManager groupManager;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void addMembersToGroup(final Set<User> users, final Group group) {
|
||||
|
||||
users.forEach(user -> addMemberToGroup(user, group));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void addMemberToGroup(final User user, final Group group) {
|
||||
|
||||
final User theUser = userRepo
|
||||
.findById(user.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
String.format("No user with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
user.getPartyId())));
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No group with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
group.getPartyId())));
|
||||
|
||||
groupManager.addMemberToGroup(theUser, theGroup);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void removeMemberFromGroup(final User member, final Group group) {
|
||||
|
||||
final User theMember = userRepo
|
||||
.findById(member.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No user with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
member.getPartyId())));
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No group with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
group.getPartyId())));
|
||||
|
||||
groupManager.removeMemberFromGroup(theMember, theGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupMembership;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class GroupMembersTableDataProvider extends AbstractDataProvider<User, String> {
|
||||
|
||||
private static final long serialVersionUID = -1924910843845830008L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private Group group;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<User, String> query) {
|
||||
|
||||
Objects.requireNonNull(group,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setGroup(Group) before calling "
|
||||
+ "the count method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||
// final Root<User> from = criteriaQuery.from(User.class);
|
||||
// final Join<?, ?> memberships = from.join("groups");
|
||||
//
|
||||
// criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
//
|
||||
// criteriaQuery.where(builder.equal(memberships.get("group"),
|
||||
// group));
|
||||
// criteriaQuery
|
||||
// .where(builder
|
||||
// .equal(builder.treat(from.get("groups"),
|
||||
// GroupMembership.class).get("group"),
|
||||
// group));
|
||||
|
||||
final Root<GroupMembership> from = criteriaQuery
|
||||
.from(GroupMembership.class);
|
||||
|
||||
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.where(builder.equal(from.get("group"), group));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<User> fetch(final Query<User, String> query) {
|
||||
|
||||
Objects.requireNonNull(group,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setGroup(Group) before calling "
|
||||
+ "the fetch method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
// final CriteriaQuery<User> criteriaQuery = builder
|
||||
// .createQuery(User.class);
|
||||
// final Root<User> from = criteriaQuery.from(User.class);
|
||||
// final Join<User, GroupMembership> memberships = from
|
||||
// .join("memberships");
|
||||
//
|
||||
// criteriaQuery.where(builder.equal(memberships.get("group"),
|
||||
// group));
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(criteriaQuery)
|
||||
// .setMaxResults(query.getLimit())
|
||||
// .setFirstResult(query.getOffset())
|
||||
// .getResultList()
|
||||
// .stream();
|
||||
|
||||
final CriteriaQuery<GroupMembership> criteriaQuery = builder
|
||||
.createQuery(GroupMembership.class);
|
||||
final Root<GroupMembership> from = criteriaQuery
|
||||
.from(GroupMembership.class);
|
||||
final Join<?, ?> join = from.join("member");
|
||||
criteriaQuery
|
||||
.where(builder.equal(from.get("group"), group))
|
||||
.orderBy(builder.asc(join.get("name")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(GroupMembership::getMember);
|
||||
}
|
||||
|
||||
public void setGroup(final Group group) {
|
||||
Objects.requireNonNull(group);
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleManager;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class GroupRolesController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 428573362835344406L;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepo;
|
||||
|
||||
@Inject
|
||||
private RoleManager roleManager;
|
||||
|
||||
@Inject
|
||||
private GroupRepository groupRepo;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignRolesToGroup(final Set<Role> roles, final Group group) {
|
||||
|
||||
roles.forEach(role -> assignRoleToGroup(role, group));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignRoleToGroup(final Role role, final Group group) {
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No group with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
group.getPartyId())));
|
||||
|
||||
roleManager.assignRoleToParty(theRole, theGroup);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void removeRoleFromGroup(final Role role, final Group group) {
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No group with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
group.getPartyId())));
|
||||
|
||||
roleManager.removeRoleFromParty(theRole, theGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleMembership;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class GroupRolesTableDataProvider extends AbstractDataProvider<Role, String> {
|
||||
|
||||
private static final long serialVersionUID = 7981493169013788121L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private Group group;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(Query<Role, String> query) {
|
||||
|
||||
Objects.requireNonNull(group,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setGroup(Group) before calling "
|
||||
+ "the count method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<RoleMembership> from = criteriaQuery
|
||||
.from(RoleMembership.class);
|
||||
|
||||
criteriaQuery
|
||||
.select(builder.count(from))
|
||||
.where(builder.equal(from.get("member"), group));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Role> fetch(Query<Role, String> query) {
|
||||
|
||||
Objects.requireNonNull(group,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setGroup(Group) before calling "
|
||||
+ "the fetch method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<RoleMembership> criteriaQuery = builder
|
||||
.createQuery(RoleMembership.class);
|
||||
final Root<RoleMembership> from = criteriaQuery
|
||||
.from(RoleMembership.class);
|
||||
final Join<?, ?> join = from.join("role");
|
||||
criteriaQuery
|
||||
.where(builder.equal(from.get("member"), group))
|
||||
.orderBy(builder.asc(join.get("name")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(RoleMembership::getRole);
|
||||
}
|
||||
|
||||
public void setGroup(final Group group) {
|
||||
Objects.requireNonNull(group);
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Group;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public interface GroupSelectionAction {
|
||||
|
||||
void action(Set<Group> selectedGroup);
|
||||
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Group;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class GroupSelector extends Window {
|
||||
|
||||
private static final long serialVersionUID = -6227551833159691370L;
|
||||
|
||||
private static final String COL_NAME = "groupname";
|
||||
|
||||
protected GroupSelector(final String caption,
|
||||
final String actionLabel,
|
||||
final GroupSelectorDataProvider dataProvider,
|
||||
final List<Group> excludedGroups,
|
||||
final GroupSelectionAction action) {
|
||||
|
||||
addWidgets(caption, actionLabel, dataProvider, excludedGroups, action);
|
||||
}
|
||||
|
||||
private void addWidgets(final String caption,
|
||||
final String actionLabel,
|
||||
final GroupSelectorDataProvider dataProvider,
|
||||
final List<Group> excludedGroups,
|
||||
final GroupSelectionAction action) {
|
||||
|
||||
setCaption(caption);
|
||||
|
||||
final Grid<Group> groupsGrid = new Grid<>();
|
||||
groupsGrid
|
||||
.addColumn(Group::getName)
|
||||
.setId(COL_NAME)
|
||||
.setCaption("Group");
|
||||
|
||||
groupsGrid.setSelectionMode(Grid.SelectionMode.MULTI);
|
||||
groupsGrid.setWidth("100%");
|
||||
|
||||
final Button actionButton = new Button(actionLabel);
|
||||
actionButton.addClickListener(event -> {
|
||||
action.action(groupsGrid.getSelectedItems());
|
||||
close();
|
||||
});
|
||||
actionButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
actionButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final Button clearButton = new Button("Clear selection");
|
||||
clearButton.addClickListener(event -> {
|
||||
groupsGrid.getSelectionModel().deselectAll();
|
||||
});
|
||||
clearButton.setIcon(VaadinIcons.BACKSPACE);
|
||||
clearButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final HeaderRow actions = groupsGrid.prependHeaderRow();
|
||||
final HeaderCell actionsCell = actions.getCell(COL_NAME);
|
||||
actionsCell.setComponent(new HorizontalLayout(actionButton,
|
||||
clearButton));
|
||||
|
||||
dataProvider.setExcludedGroups(excludedGroups);
|
||||
groupsGrid.setDataProvider(dataProvider);
|
||||
|
||||
setContent(groupsGrid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Group;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class GroupSelectorDataProvider extends AbstractDataProvider<Group, String> {
|
||||
|
||||
private static final long serialVersionUID = 2237927716392108777L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private String groupNameFilter;
|
||||
|
||||
private List<Group> excludedGroups;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Group, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<Group> from = criteriaQuery.from(Group.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.distinct(true);
|
||||
|
||||
if (groupNameFilter != null && !groupNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", groupNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedGroups != null && !excludedGroups.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedGroups)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Group> fetch(final Query<Group, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Group> criteriaQuery = builder
|
||||
.createQuery(Group.class);
|
||||
final Root<Group> from = criteriaQuery.from(Group.class);
|
||||
criteriaQuery.distinct(true);
|
||||
|
||||
if (groupNameFilter != null && !groupNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", groupNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedGroups != null && !excludedGroups.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedGroups)));
|
||||
}
|
||||
|
||||
criteriaQuery.orderBy(builder.asc(from.get("name")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
public void setGroupNameFilter(final String groupNameFilter) {
|
||||
this.groupNameFilter = groupNameFilter;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
public void setExcludedGroups(final List<Group> excludedGroups) {
|
||||
this.excludedGroups = excludedGroups;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.security.GroupManager;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class GroupsController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4112198806815494041L;
|
||||
|
||||
@Inject
|
||||
private GroupManager groupManager;
|
||||
|
||||
@Inject
|
||||
private GroupMembersController membersController;
|
||||
|
||||
@Inject
|
||||
private GroupMembersTableDataProvider membersTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private GroupRepository groupRepository;
|
||||
|
||||
@Inject
|
||||
private GroupsTableDataProvider groupsTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private GroupRolesController rolesController;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepository;
|
||||
|
||||
@Inject
|
||||
private GroupRolesTableDataProvider rolesTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private RoleSelectorDataProvider roleSelectorDataProvider;
|
||||
|
||||
@Inject
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Inject
|
||||
private UserSelectorDataProvider userSelectorDataProvider;
|
||||
|
||||
protected GroupManager getGroupManager() {
|
||||
return groupManager;
|
||||
}
|
||||
|
||||
protected GroupMembersController getMembersController() {
|
||||
return membersController;
|
||||
}
|
||||
|
||||
protected GroupMembersTableDataProvider getMembersTableDataProvider() {
|
||||
return membersTableDataProvider;
|
||||
}
|
||||
|
||||
protected GroupRepository getGroupRepository() {
|
||||
return groupRepository;
|
||||
}
|
||||
|
||||
protected GroupsTableDataProvider getGroupsTableDataProvider() {
|
||||
return groupsTableDataProvider;
|
||||
}
|
||||
|
||||
protected GroupRolesController getRolesController() {
|
||||
return rolesController;
|
||||
}
|
||||
|
||||
protected RoleRepository getRoleRepository() {
|
||||
return roleRepository;
|
||||
}
|
||||
|
||||
protected GroupRolesTableDataProvider getRolesTableDataProvider() {
|
||||
return rolesTableDataProvider;
|
||||
}
|
||||
|
||||
protected RoleSelectorDataProvider getRoleSelectorDataProvider() {
|
||||
return roleSelectorDataProvider;
|
||||
}
|
||||
|
||||
protected UserRepository getUserRepository() {
|
||||
return userRepository;
|
||||
}
|
||||
|
||||
protected UserSelectorDataProvider getUserSelectorDataProvider() {
|
||||
return userSelectorDataProvider;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class GroupsTable extends Grid<Group> {
|
||||
|
||||
private static final long serialVersionUID = 2731047837262813862L;
|
||||
|
||||
private final static String COL_NAME = "name";
|
||||
private final static String COL_EDIT = "edit";
|
||||
private final static String COL_DELETE = "delete";
|
||||
|
||||
private final TextField groupNameFilter;
|
||||
private final Button clearFiltersButton;
|
||||
private final Button createGroupButton;
|
||||
|
||||
protected GroupsTable(final UsersGroupsRolesController controller) {
|
||||
|
||||
super();
|
||||
|
||||
super.setDataProvider(controller.getGroupsTableDataProvider());
|
||||
|
||||
final GlobalizationHelper globalizationHelper = controller
|
||||
.getGlobalizationHelper();
|
||||
|
||||
final LocalizedTextsUtil adminBundle = globalizationHelper
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
addColumn(Group::getName)
|
||||
.setId(COL_NAME)
|
||||
.setCaption(adminBundle.getText("ui.admin.groups.table.name"));
|
||||
addComponentColumn(group -> {
|
||||
final Button editButton = new Button(
|
||||
adminBundle.getText("ui.admin.groups.table.edit"),
|
||||
VaadinIcons.EDIT);
|
||||
editButton.addClickListener(event -> {
|
||||
final GroupDetails groupDetails = new GroupDetails(
|
||||
group,
|
||||
controller.getGroupsController());
|
||||
groupDetails.setModal(true);
|
||||
groupDetails.center();
|
||||
groupDetails.setWidth("50%");
|
||||
groupDetails.setHeight("100%");
|
||||
UI.getCurrent().addWindow(groupDetails);
|
||||
});
|
||||
editButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
return editButton;
|
||||
})
|
||||
.setId(COL_EDIT);
|
||||
addComponentColumn(group -> {
|
||||
final Button deleteButton = new Button(adminBundle.getText(
|
||||
"ui.admin.groups.table.delete"),
|
||||
VaadinIcons.CLOSE_CIRCLE_O);
|
||||
deleteButton.addClickListener(event -> {
|
||||
final ConfirmDeleteDialog dialog = new ConfirmDeleteDialog(
|
||||
group, controller.getGroupRepository(), adminBundle);
|
||||
dialog.setModal(true);
|
||||
dialog.center();
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
});
|
||||
deleteButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return deleteButton;
|
||||
})
|
||||
.setId(COL_DELETE);
|
||||
|
||||
final HeaderRow filterRow = appendHeaderRow();
|
||||
final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME);
|
||||
groupNameFilter = new TextField();
|
||||
groupNameFilter.setPlaceholder(adminBundle
|
||||
.getText("ui.admin.users.table.filter.groupname.placeholder"));
|
||||
groupNameFilter.setDescription(adminBundle
|
||||
.getText("ui.admin.users.table.filter.groupname.description"));
|
||||
groupNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY);
|
||||
groupNameFilter
|
||||
.addValueChangeListener(event -> {
|
||||
((GroupsTableDataProvider) getDataProvider())
|
||||
.setGroupNameFilter(event.getValue().toLowerCase());
|
||||
});
|
||||
GroupNameFilterCell.setComponent(groupNameFilter);
|
||||
|
||||
final HeaderRow actionsRow = prependHeaderRow();
|
||||
final HeaderCell actionsCell = actionsRow.join(COL_NAME,
|
||||
COL_EDIT,
|
||||
COL_DELETE);
|
||||
clearFiltersButton = new Button(adminBundle
|
||||
.getText("ui.admin.users.table.filter.clear"));
|
||||
clearFiltersButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
clearFiltersButton.setIcon(VaadinIcons.BACKSPACE);
|
||||
clearFiltersButton.addClickListener(event -> {
|
||||
groupNameFilter.setValue("");
|
||||
});
|
||||
|
||||
createGroupButton = new Button("New group");
|
||||
createGroupButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
createGroupButton.setIcon(VaadinIcons.PLUS);
|
||||
createGroupButton.addClickListener(event -> {
|
||||
final GroupEditor groupEditor = new GroupEditor(
|
||||
controller.getGroupRepository());
|
||||
groupEditor.addCloseListener(closeEvent -> {
|
||||
getDataProvider().refreshAll();
|
||||
});
|
||||
groupEditor.center();
|
||||
UI.getCurrent().addWindow(groupEditor);
|
||||
});
|
||||
final HorizontalLayout actionsLayout = new HorizontalLayout(
|
||||
clearFiltersButton,
|
||||
createGroupButton);
|
||||
actionsCell.setComponent(actionsLayout);
|
||||
}
|
||||
|
||||
private class ConfirmDeleteDialog extends Window {
|
||||
|
||||
private static final long serialVersionUID = -1168912882249598278L;
|
||||
|
||||
private final Group group;
|
||||
private final GroupRepository groupRepo;
|
||||
|
||||
public ConfirmDeleteDialog(final Group group,
|
||||
final GroupRepository groupRepo,
|
||||
final LocalizedTextsUtil adminBundle) {
|
||||
|
||||
this.group = group;
|
||||
this.groupRepo = groupRepo;
|
||||
|
||||
final MessageFormat messageFormat = new MessageFormat(
|
||||
adminBundle.getText("ui.admin.groups.delete.confirm"));
|
||||
|
||||
final Label text = new Label(messageFormat
|
||||
.format(new Object[]{group.getName()}));
|
||||
|
||||
final Button yesButton
|
||||
= new Button(adminBundle.getText("ui.admin.yes"));
|
||||
yesButton.addClickListener(event -> deleteGroup());
|
||||
|
||||
final Button noButton = new Button(adminBundle
|
||||
.getText("ui.admin.no"));
|
||||
noButton.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttons = new HorizontalLayout(yesButton,
|
||||
noButton);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(text, buttons);
|
||||
|
||||
super.setContent(layout);
|
||||
}
|
||||
|
||||
private void deleteGroup() {
|
||||
groupRepo.delete(group);
|
||||
getDataProvider().refreshAll();
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Group;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class GroupsTableDataProvider extends AbstractDataProvider<Group, String> {
|
||||
|
||||
private static final long serialVersionUID = 7341726757450723593L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private String groupNameFilter;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Group, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||
final Root<Group> from = criteriaQuery.from(Group.class);
|
||||
|
||||
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
|
||||
if (groupNameFilter != null && !groupNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", groupNameFilter)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Group> fetch(final Query<Group, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Group> criteriaQuery = builder
|
||||
.createQuery(Group.class);
|
||||
final Root<Group> from = criteriaQuery.from(Group.class);
|
||||
|
||||
if (groupNameFilter != null && !groupNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", groupNameFilter)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
public void setGroupNameFilter(final String groupNameFilter) {
|
||||
this.groupNameFilter = groupNameFilter;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* To change this license layout, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.libreccm.admin.ui;
|
||||
|
||||
import com.vaadin.server.ClassResource;
|
||||
import com.vaadin.server.VaadinServlet;
|
||||
import com.vaadin.ui.*;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class Header extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = -8503268025688988953L;
|
||||
|
||||
public Header() {
|
||||
super();
|
||||
|
||||
final ServletContext servletContext = VaadinServlet
|
||||
.getCurrent()
|
||||
.getServletContext();
|
||||
|
||||
final GridLayout layout = new GridLayout(5, 1);
|
||||
layout.setWidth("100%");
|
||||
layout.addStyleName("libreccm-header");
|
||||
|
||||
final Label headerInfoLine = new Label("LibreCCM");
|
||||
headerInfoLine.setId("libreccm-headerinfoline");
|
||||
layout.addComponent(headerInfoLine, 3, 0, 4, 0);
|
||||
layout.setComponentAlignment(headerInfoLine, Alignment.TOP_RIGHT);
|
||||
|
||||
final String logoPath;
|
||||
switch (servletContext.getInitParameter("ccm.distribution")
|
||||
.toLowerCase()) {
|
||||
case "libreccm":
|
||||
logoPath = "/themes/libreccm-default/images/libreccm.png";
|
||||
break;
|
||||
case "librecms":
|
||||
logoPath = "/themes/libreccm-default/images/librecms.png";
|
||||
break;
|
||||
case "aplaws":
|
||||
logoPath = "/themes/libreccm-default/images/aplaws.png";
|
||||
break;
|
||||
case "scientificcms":
|
||||
logoPath = "/themes/libreccm-default/images/scientificcms.png";
|
||||
break;
|
||||
default:
|
||||
logoPath = "/themes/libreccm-default/images/libreccm.png";
|
||||
break;
|
||||
}
|
||||
|
||||
final Image logo = new Image(null, new ClassResource(logoPath));
|
||||
logo.setId("libreccm-logo");
|
||||
logo.addStyleName("libreccm-logo");
|
||||
layout.addComponent(logo, 0, 0);
|
||||
layout.setComponentAlignment(logo, Alignment.MIDDLE_LEFT);
|
||||
|
||||
super.setCompositionRoot(layout);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,424 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.data.ValueProvider;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.AbstractComponent;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class JpqlConsole extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = 2585630538827827614L;
|
||||
private static final Logger LOGGER = LogManager.getLogger(JpqlConsole.class);
|
||||
|
||||
private final JpqlConsoleController controller;
|
||||
|
||||
private final TextArea queryArea;
|
||||
private final TextField maxResults;
|
||||
private final TextField offset;
|
||||
private final Button executeQueryButton;
|
||||
// private final FormLayout queryForm;
|
||||
// private final VerticalLayout resultsLayout;
|
||||
private final Label noResultsLabel;
|
||||
private final Panel resultsPanel;
|
||||
|
||||
JpqlConsole(final JpqlConsoleController controller) {
|
||||
|
||||
this.controller = controller;
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle.getBundle(
|
||||
AdminUiConstants.ADMIN_BUNDLE, UI.getCurrent().getLocale());
|
||||
|
||||
queryArea = new TextArea(bundle.getString("ui.admin.jpqlconsole.query"));
|
||||
queryArea.setWidth("100%");
|
||||
executeQueryButton = new Button(bundle
|
||||
.getString("ui.admin.jpqlconsole.query.execute"));
|
||||
executeQueryButton.addClickListener(event -> executeQuery());
|
||||
final Button clearQueryButton = new Button(bundle
|
||||
.getString("ui.admin.jpqlconsole.query.clear"));
|
||||
clearQueryButton.addClickListener(event -> queryArea.clear());
|
||||
final HorizontalLayout queryButtonsLayout = new HorizontalLayout(
|
||||
clearQueryButton,
|
||||
executeQueryButton);
|
||||
maxResults = new TextField("Max results", "10");
|
||||
maxResults.addValueChangeListener(new NumberValidator());
|
||||
offset = new TextField("Offset", "0");
|
||||
offset.addValueChangeListener(new NumberValidator());
|
||||
final HorizontalLayout maxResultsLayout = new HorizontalLayout(
|
||||
maxResults, offset);
|
||||
|
||||
final VerticalLayout queryLayout = new VerticalLayout(queryArea,
|
||||
maxResultsLayout,
|
||||
queryButtonsLayout);
|
||||
|
||||
noResultsLabel = new Label(bundle
|
||||
.getString("ui.admin.jpqlconsole.results.none"));
|
||||
resultsPanel = new Panel("Query results",
|
||||
noResultsLabel);
|
||||
|
||||
// resultsLayout = new VerticalLayout(noResultsLabel);
|
||||
// final VerticalSplitPanel splitPanel = new VerticalSplitPanel();
|
||||
//// splitPanel.setSizeFull();
|
||||
// splitPanel.setHeight("100%");
|
||||
// splitPanel.setSplitPosition(33.3f, Unit.PERCENTAGE);
|
||||
// splitPanel.setFirstComponent(queryForm);
|
||||
// splitPanel.setSecondComponent(resultsLayout);
|
||||
super.setCompositionRoot(new VerticalLayout(queryLayout, resultsPanel));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void executeQuery() {
|
||||
final String queryStr = queryArea.getValue();
|
||||
|
||||
if (queryStr == null || queryStr.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!queryStr.toLowerCase().startsWith("select")) {
|
||||
Notification.show("Only SELECT queries",
|
||||
"Only SELECT queries are supported",
|
||||
Notification.Type.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<?> result;
|
||||
try {
|
||||
result = controller
|
||||
.executeQuery(queryStr,
|
||||
Integer.parseInt(maxResults.getValue()),
|
||||
Integer.parseInt(offset.getValue()));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Notification.show("Query is malformed.",
|
||||
ex.getMessage(),
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
return;
|
||||
} catch (PersistenceException ex) {
|
||||
Notification.show("Failed to execute query",
|
||||
ex.getMessage(),
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Class<?>> classes = result
|
||||
.stream()
|
||||
.map(Object::getClass)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final Set<EntityPropertyDescriptor> entityProperties = new HashSet<>();
|
||||
try {
|
||||
for (final Class<?> clazz : classes) {
|
||||
final BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
|
||||
final PropertyDescriptor[] props = beanInfo
|
||||
.getPropertyDescriptors();
|
||||
|
||||
for (final PropertyDescriptor prop : props) {
|
||||
entityProperties.add(createEntityPropertyDescriptor(clazz,
|
||||
prop));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (final Class<?> clazz : classes) {
|
||||
final BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
|
||||
final List<EntityPropertyDescriptor> props = Arrays
|
||||
.stream(beanInfo.getPropertyDescriptors())
|
||||
.map(prop -> createEntityPropertyDescriptor(clazz,
|
||||
prop))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
entityProperties.retainAll(props);
|
||||
}
|
||||
} catch (IntrospectionException ex) {
|
||||
Notification.show(
|
||||
"Error displaying result. Failed to introspect classes.",
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<EntityPropertyDescriptor> propertiesList = entityProperties
|
||||
.stream()
|
||||
.filter(prop -> {
|
||||
return !Collection.class
|
||||
.isAssignableFrom(prop
|
||||
.getPropertyDescriptor()
|
||||
.getPropertyType());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
Collections.sort(propertiesList);
|
||||
|
||||
// final List<String> propertyNames = propertiesList
|
||||
// .stream()
|
||||
// .map(prop -> prop.getPropertyDescriptor().getName())
|
||||
// .collect(Collectors.toList());
|
||||
final Label count = new Label(String.format("Found %d results",
|
||||
result.size()));
|
||||
// final Label propertiesLabel = new Label(String.join(", ",
|
||||
// propertyNames));
|
||||
|
||||
final Grid<Object> resultsGrid = new Grid<>(Object.class);
|
||||
resultsGrid.setWidth("100%");
|
||||
for (final EntityPropertyDescriptor property : propertiesList) {
|
||||
resultsGrid.addColumn(new ValueProvider<Object, Object>() {
|
||||
|
||||
private static final long serialVersionUID
|
||||
= 8400673589843188514L;
|
||||
|
||||
@Override
|
||||
public Object apply(final Object source) {
|
||||
final Method readMethod = property
|
||||
.getPropertyDescriptor()
|
||||
.getReadMethod();
|
||||
try {
|
||||
return readMethod.invoke(source);
|
||||
} catch (IllegalAccessException
|
||||
| IllegalArgumentException
|
||||
| InvocationTargetException ex) {
|
||||
Notification.show("Failed to display some properties.",
|
||||
Notification.Type.WARNING_MESSAGE);
|
||||
LOGGER.error("Failed to display property '{}'.",
|
||||
property.getPropertyDescriptor().getName());
|
||||
LOGGER.error(ex);
|
||||
return ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
.setCaption(property.getPropertyDescriptor().getName());
|
||||
}
|
||||
resultsGrid.setItems((Collection<Object>) result);
|
||||
|
||||
// final VerticalLayout data = new VerticalLayout(count, propertiesLabel);
|
||||
final VerticalLayout data = new VerticalLayout(count, resultsGrid);
|
||||
resultsPanel.setContent(data);
|
||||
|
||||
}
|
||||
|
||||
private boolean isIdProperty(final Class<?> clazz,
|
||||
final PropertyDescriptor property) {
|
||||
|
||||
final String propertyName = property.getName();
|
||||
final Optional<Field> field = getField(clazz, propertyName);
|
||||
final Method readMethod = property.getReadMethod();
|
||||
|
||||
return (field.isPresent() && field.get().isAnnotationPresent(Id.class)
|
||||
|| (readMethod != null && readMethod.isAnnotationPresent(
|
||||
Id.class)));
|
||||
}
|
||||
|
||||
private Optional<Field> getField(final Class<?> clazz, final String name) {
|
||||
|
||||
try {
|
||||
return Optional.of(clazz.getDeclaredField(name));
|
||||
} catch (NoSuchFieldException ex) {
|
||||
|
||||
if (Object.class.equals(clazz.getSuperclass())) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return getField(clazz.getSuperclass(), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityPropertyDescriptor createEntityPropertyDescriptor(
|
||||
final Class<?> clazz,
|
||||
final PropertyDescriptor propertyDescriptor) {
|
||||
|
||||
return new EntityPropertyDescriptor(
|
||||
propertyDescriptor,
|
||||
"class".equals(propertyDescriptor.getName()),
|
||||
isIdProperty(clazz, propertyDescriptor));
|
||||
|
||||
}
|
||||
|
||||
private class EntityPropertyDescriptor
|
||||
implements Comparable<EntityPropertyDescriptor> {
|
||||
|
||||
private final PropertyDescriptor propertyDescriptor;
|
||||
private final boolean classProperty;
|
||||
private final boolean idProperty;
|
||||
|
||||
public EntityPropertyDescriptor(
|
||||
final PropertyDescriptor propertyDescriptor,
|
||||
final boolean classProperty,
|
||||
final boolean idProperty) {
|
||||
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
this.classProperty = classProperty;
|
||||
this.idProperty = idProperty;
|
||||
}
|
||||
|
||||
public PropertyDescriptor getPropertyDescriptor() {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public boolean isClassProperty() {
|
||||
return classProperty;
|
||||
}
|
||||
|
||||
public boolean isIdProperty() {
|
||||
return idProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 13 * hash + Objects.hashCode(propertyDescriptor);
|
||||
hash = 13 * hash + (classProperty ? 1 : 0);
|
||||
hash = 13 * hash + (idProperty ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof EntityPropertyDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
final EntityPropertyDescriptor other
|
||||
= (EntityPropertyDescriptor) obj;
|
||||
if (classProperty != other.isClassProperty()) {
|
||||
return false;
|
||||
}
|
||||
if (idProperty != other.isIdProperty()) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(propertyDescriptor,
|
||||
other.getPropertyDescriptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final EntityPropertyDescriptor other) {
|
||||
|
||||
if (isIdProperty() && other.isIdProperty()) {
|
||||
return propertyDescriptor
|
||||
.getName()
|
||||
.compareTo(other.getPropertyDescriptor().getName());
|
||||
} else if (isIdProperty() && other.isClassProperty()) {
|
||||
return -1;
|
||||
} else if (isClassProperty() && other.isIdProperty()) {
|
||||
return 1;
|
||||
} else if (isIdProperty()) {
|
||||
return -1;
|
||||
} else if (other.isIdProperty()) {
|
||||
return 1;
|
||||
} else if (isClassProperty()) {
|
||||
return -1;
|
||||
} else if (other.isClassProperty()) {
|
||||
return 1;
|
||||
} else {
|
||||
return propertyDescriptor
|
||||
.getName()
|
||||
.compareTo(other.getPropertyDescriptor().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s{ "
|
||||
+ "name = '%s'; "
|
||||
+ "readMethod = '%s'; "
|
||||
+ "writeMethod = '%s'; "
|
||||
+ "type = '%s'; "
|
||||
+ "isIdProperty = '%b'; "
|
||||
+ "isClassProperty = '%b';"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
propertyDescriptor.getName(),
|
||||
propertyDescriptor.getReadMethod().getName(),
|
||||
propertyDescriptor.getWriteMethod().getName(),
|
||||
propertyDescriptor.getPropertyType().getName(),
|
||||
idProperty,
|
||||
classProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class NumberValidator
|
||||
implements HasValue.ValueChangeListener<String> {
|
||||
|
||||
private static final long serialVersionUID = -3604431972616625411L;
|
||||
|
||||
@Override
|
||||
public void valueChange(
|
||||
final HasValue.ValueChangeEvent<String> event) {
|
||||
final String value = event.getValue();
|
||||
try {
|
||||
Integer.parseUnsignedInt(value);
|
||||
} catch (NumberFormatException ex) {
|
||||
executeQueryButton.setEnabled(false);
|
||||
((AbstractComponent) event.getComponent()).setComponentError(
|
||||
new UserError(String.format(
|
||||
"%s is not a unsigned integer/long value.",
|
||||
event.getComponent().getCaption())));
|
||||
return;
|
||||
}
|
||||
|
||||
((AbstractComponent) event.getComponent()).setComponentError(null);
|
||||
executeQueryButton.setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class JpqlConsoleController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1625999285594476564L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected List<?> executeQuery(final String queryStr,
|
||||
final int maxResults,
|
||||
final int offset) {
|
||||
|
||||
Objects.requireNonNull(queryStr);
|
||||
|
||||
final Query query = entityManager.createQuery(queryStr);
|
||||
query.setMaxResults(maxResults);
|
||||
query.setFirstResult(offset);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.CDIView;
|
||||
import org.libreccm.ui.AbstractLoginView;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@CDIView(value = LoginView.VIEWNAME,
|
||||
uis = {AdminUIVaadin.class})
|
||||
//public class LoginView extends CustomComponent implements View {
|
||||
|
||||
public class LoginView extends AbstractLoginView {
|
||||
|
||||
private static final long serialVersionUID = 997966222985596011L;
|
||||
|
||||
public static final String VIEWNAME = "adminlogin";
|
||||
|
||||
@Override
|
||||
protected String getTargetView() {
|
||||
return AdminView.VIEWNAME;
|
||||
}
|
||||
|
||||
// @Inject
|
||||
// private ConfigurationManager confManager;
|
||||
//
|
||||
// @Inject
|
||||
// private GlobalizationHelper globalizationHelper;
|
||||
//
|
||||
// @Inject
|
||||
// private Subject subject;
|
||||
//
|
||||
// private ResourceBundle bundle;
|
||||
//
|
||||
// private final Panel loginPanel;
|
||||
// private final FormLayout formLayout;
|
||||
// private final TextField userName;
|
||||
// private final TextField password;
|
||||
// private final Button submitButton;
|
||||
//
|
||||
// public LoginView() {
|
||||
//
|
||||
// formLayout = new FormLayout();
|
||||
// formLayout.setSizeFull();
|
||||
// formLayout.setMargin(true);
|
||||
//
|
||||
// userName = new TextField();
|
||||
// userName.setCaption("User name");
|
||||
// formLayout.addComponent(userName);
|
||||
//
|
||||
// password = new PasswordField("Password");
|
||||
// formLayout.addComponent(password);
|
||||
//
|
||||
// submitButton = new Button("Login");
|
||||
// submitButton.addClickListener(event -> login(event));
|
||||
// submitButton.setEnabled(false);
|
||||
// formLayout.addComponent(submitButton);
|
||||
//
|
||||
// userName.addValueChangeListener(event -> {
|
||||
// if (userName.getValue() != null
|
||||
// && !userName.getValue().trim().isEmpty()
|
||||
// && password.getValue() != null
|
||||
// && !password.getValue().trim().isEmpty()) {
|
||||
// submitButton.setEnabled(true);
|
||||
// submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// password.addValueChangeListener(event -> {
|
||||
// if (userName.getValue() != null
|
||||
// && !userName.getValue().trim().isEmpty()
|
||||
// && password.getValue() != null
|
||||
// && !password.getValue().trim().isEmpty()) {
|
||||
// submitButton.setEnabled(true);
|
||||
// submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
//// userName.addFocusListener(event -> {
|
||||
//// if (userName.getValue() != null
|
||||
//// && !userName.getValue().trim().isEmpty()
|
||||
//// && password.getValue() != null
|
||||
//// && !password.getValue().trim().isEmpty()) {
|
||||
//// submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
|
||||
//// }
|
||||
//// });
|
||||
//// userName.addBlurListener(event -> {
|
||||
//// if (userName.getValue() != null
|
||||
//// && !userName.getValue().trim().isEmpty()
|
||||
//// && password.getValue() != null
|
||||
//// && !password.getValue().trim().isEmpty()) {
|
||||
//// submitButton.removeClickShortcut();
|
||||
//// }
|
||||
//// });
|
||||
// password.addFocusListener(event -> {
|
||||
// submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
|
||||
// });
|
||||
// password.addBlurListener(event -> {
|
||||
// submitButton.removeClickShortcut();
|
||||
// });
|
||||
//
|
||||
// loginPanel = new Panel("Login", formLayout);
|
||||
// loginPanel.setWidth("27em");
|
||||
//
|
||||
// final VerticalLayout viewLayout = new VerticalLayout(new Header(),
|
||||
// loginPanel);
|
||||
//
|
||||
// viewLayout.setComponentAlignment(loginPanel, Alignment.MIDDLE_CENTER);
|
||||
//
|
||||
// super.setCompositionRoot(viewLayout);
|
||||
// }
|
||||
//
|
||||
// @PostConstruct
|
||||
// private void postConstruct() {
|
||||
// bundle = ResourceBundle.getBundle(
|
||||
// "com.arsdigita.ui.login.LoginResources",
|
||||
// globalizationHelper.getNegotiatedLocale());
|
||||
// }
|
||||
//
|
||||
// private void login(final Button.ClickEvent event) {
|
||||
// final UsernamePasswordToken token = new UsernamePasswordToken(
|
||||
// userName.getValue(),
|
||||
// password.getValue());
|
||||
// token.setRememberMe(true);
|
||||
//
|
||||
// try {
|
||||
// subject.login(token);
|
||||
// } catch (AuthenticationException ex) {
|
||||
// submitButton.setComponentError(
|
||||
// new UserError(bundle.getString("login.error.loginFail")));
|
||||
// Notification.show(bundle.getString("login.error.loginFail"),
|
||||
// Notification.Type.ERROR_MESSAGE);
|
||||
// password.setValue("");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// getUI().getNavigator().navigateTo(AdminView.VIEWNAME);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void enter(final ViewChangeListener.ViewChangeEvent event) {
|
||||
//
|
||||
// final KernelConfig kernelConfig = confManager
|
||||
// .findConfiguration(KernelConfig.class
|
||||
// );
|
||||
// loginPanel
|
||||
// .setCaption(bundle.getString("login.userRegistrationForm.title"));
|
||||
// if (kernelConfig.emailIsPrimaryIdentifier()) {
|
||||
// userName.setCaption(bundle
|
||||
// .getString("login.userRegistrationForm.email"));
|
||||
// } else {
|
||||
// userName.setCaption(bundle
|
||||
// .getString("login.userRegistrationForm.screenName"));
|
||||
// }
|
||||
// password.setCaption(
|
||||
// bundle.getString("login.userRegistrationForm.password"));
|
||||
//
|
||||
// submitButton.setCaption(bundle
|
||||
// .getString("login.userRegistrationForm.title"));
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.pagemodel.ComponentModelRepository;
|
||||
import org.libreccm.pagemodel.PageModelManager;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class PageModelComponentEditorController {
|
||||
|
||||
@Inject
|
||||
private ComponentModelRepository componentModelRepository;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private PageModelsController pageModelsController;
|
||||
|
||||
@Inject
|
||||
private PageModelManager pageModelManager;
|
||||
|
||||
@Inject
|
||||
private PageModelsTableDataProvider pageModelsTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private PageModelComponentModelsTableDataProvider pageModelComponentModelsTableDataProvider;
|
||||
|
||||
public ComponentModelRepository getComponentModelRepository() {
|
||||
return componentModelRepository;
|
||||
}
|
||||
|
||||
public GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
public PageModelsController getPageModelsController() {
|
||||
return pageModelsController;
|
||||
}
|
||||
|
||||
public PageModelManager getPageModelManager() {
|
||||
return pageModelManager;
|
||||
}
|
||||
|
||||
public void refreshPageModelsTable() {
|
||||
pageModelsTableDataProvider.refreshAll();
|
||||
}
|
||||
|
||||
public void refreshComponentModels() {
|
||||
pageModelComponentModelsTableDataProvider.refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.ComponentModels;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PageModelComponentModelTypesDataProvider
|
||||
extends AbstractDataProvider<PageModelComponentModel, String> {
|
||||
|
||||
private static final long serialVersionUID = -27393177360237040L;
|
||||
|
||||
@Inject
|
||||
private ComponentModels componentModels;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<PageModelComponentModel, String> query) {
|
||||
|
||||
final Optional<String> filter = query.getFilter();
|
||||
|
||||
if (filter.isPresent()) {
|
||||
return (int) componentModels
|
||||
.findAvailableComponentModels()
|
||||
.stream()
|
||||
.filter(model -> filterModels(model, filter.get()))
|
||||
.count();
|
||||
|
||||
} else {
|
||||
return componentModels
|
||||
.findAvailableComponentModels()
|
||||
.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<PageModelComponentModel> fetch(
|
||||
final Query<PageModelComponentModel, String> query) {
|
||||
|
||||
final Optional<String> filter = query.getFilter();
|
||||
|
||||
if (filter.isPresent()) {
|
||||
return componentModels
|
||||
.findAvailableComponentModels()
|
||||
.stream()
|
||||
.filter(model -> filterModels(model, filter.get()));
|
||||
} else {
|
||||
return componentModels
|
||||
.findAvailableComponentModels()
|
||||
.stream();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filterModels(final PageModelComponentModel model,
|
||||
final String filter) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(model.descBundle());
|
||||
|
||||
final String title = textsUtil
|
||||
.getText(textsUtil.getText(model.titleKey()));
|
||||
|
||||
return title.startsWith(filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.pagemodel.ComponentModel;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelRepository;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PageModelComponentModelsTableDataProvider
|
||||
extends AbstractBackEndDataProvider<ComponentModel, String> {
|
||||
|
||||
private static final long serialVersionUID = -8880329002442808769L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private PageModelRepository pageModelRepo;
|
||||
|
||||
private PageModel pageModel;
|
||||
|
||||
protected PageModel getPageModel() {
|
||||
return pageModel;
|
||||
}
|
||||
|
||||
protected void setPageModel(final PageModel pageModel) {
|
||||
Objects.requireNonNull(pageModel);
|
||||
this.pageModel = pageModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected Stream<ComponentModel> fetchFromBackEnd(
|
||||
final Query<ComponentModel, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<ComponentModel> criteriaQuery = builder
|
||||
.createQuery(ComponentModel.class);
|
||||
final Root<ComponentModel> from = criteriaQuery
|
||||
.from(ComponentModel.class);
|
||||
criteriaQuery.where(builder.equal(from.get("pageModel"), pageModel));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected int sizeInBackEnd(final Query<ComponentModel, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<ComponentModel> from = criteriaQuery
|
||||
.from(ComponentModel.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.where(builder.equal(from.get("pageModel"), pageModel));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
// return retrievePageModel().getComponents().size();
|
||||
}
|
||||
|
||||
private PageModel retrievePageModel() {
|
||||
|
||||
return pageModelRepo
|
||||
.findById(pageModel.getPageModelId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No PageModel with ID %d in the database.",
|
||||
pageModel.getPageModelId())));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,407 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.ComponentModel;
|
||||
import org.libreccm.pagemodel.ComponentModels;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.libreccm.ui.ConfirmDialog;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PageModelDetails extends Window {
|
||||
|
||||
private static final long serialVersionUID = -3617001410191320596L;
|
||||
|
||||
private static final String COL_KEY = "key";
|
||||
private static final String COL_TYPE = "type";
|
||||
private static final String COL_EDIT = "edit";
|
||||
private static final String COL_DEL = "del";
|
||||
|
||||
private final AdminViewController controller;
|
||||
private final CcmApplication application;
|
||||
private final PageModel pageModel;
|
||||
|
||||
// private final NativeSelect<PageModelComponentModel> componentModelTypeSelect;
|
||||
private final ComboBox<PageModelComponentModel> componentModelTypeSelect;
|
||||
|
||||
PageModelDetails(final PageModel pageModel,
|
||||
final CcmApplication application,
|
||||
final AdminViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
this.application = application;
|
||||
this.pageModel = pageModel;
|
||||
|
||||
final GlobalizationHelper globalizationHelper = controller
|
||||
.getGlobalizationHelper();
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
final ConfigurationManager configurationManager = controller
|
||||
.getConfigurationManager();
|
||||
final KernelConfig kernelConfig = configurationManager
|
||||
.findConfiguration(KernelConfig.class);
|
||||
final Locale defaultLocale = kernelConfig.getDefaultLocale();
|
||||
|
||||
super.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.details.heading",
|
||||
new String[]{pageModel.getName()}));
|
||||
|
||||
final Label nameLabel = new Label(pageModel.getName());
|
||||
nameLabel.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.details.model_name"));
|
||||
|
||||
final Label titleLabel = new Label(pageModel
|
||||
.getTitle().getValue(defaultLocale));
|
||||
titleLabel.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.details.model_title"));
|
||||
|
||||
final Label applicationLabel = new Label(pageModel
|
||||
.getApplication().getPrimaryUrl());
|
||||
applicationLabel.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.details.model_application"));
|
||||
|
||||
final Label descLabel = new Label(pageModel
|
||||
.getDescription().getValue(defaultLocale));
|
||||
descLabel.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.details.model_desc"));
|
||||
|
||||
final FormLayout propertiesSheetLayout = new FormLayout(
|
||||
nameLabel, titleLabel, applicationLabel, descLabel);
|
||||
|
||||
final Button editPropertiesButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.edit_basic_properties"));
|
||||
editPropertiesButton.setIcon(VaadinIcons.EDIT);
|
||||
editPropertiesButton
|
||||
.addClickListener(this::editBasicPropertiesButtonClicked);
|
||||
final HorizontalLayout buttonsLayout = new HorizontalLayout(
|
||||
editPropertiesButton);
|
||||
|
||||
final PageModelsController pageModelsController = controller
|
||||
.getPageModelsController();
|
||||
|
||||
final Grid<ComponentModel> componentsModelGrid = new Grid<>();
|
||||
final PageModelComponentModelsTableDataProvider dataProvider
|
||||
= pageModelsController
|
||||
.getComponentModelsTableDataProvider();
|
||||
dataProvider.setPageModel(pageModel);
|
||||
componentsModelGrid.setDataProvider(dataProvider);
|
||||
componentsModelGrid
|
||||
.addColumn(ComponentModel::getKey)
|
||||
.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.componentmodels.cols.key.heading"))
|
||||
.setId(COL_KEY);
|
||||
componentsModelGrid
|
||||
.addColumn(this::getComponentModelType)
|
||||
.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.componentmodels.cols.type.heading"))
|
||||
.setId(COL_TYPE);
|
||||
componentsModelGrid
|
||||
.addComponentColumn(this::buildEditButton)
|
||||
.setCaption(textsUtil
|
||||
.getText("ui.admin.pagemodels.componentmodels.cols.edit.heading"))
|
||||
.setId(COL_EDIT);
|
||||
componentsModelGrid
|
||||
.addComponentColumn(this::buildDeleteButton)
|
||||
.setCaption(textsUtil
|
||||
.getText(
|
||||
"ui.admin.pagemodels.componentmodels.cols.delete.heading"))
|
||||
.setId(COL_DEL);
|
||||
componentsModelGrid.setWidth("100%");
|
||||
|
||||
// componentModelTypeSelect = new NativeSelect<>(
|
||||
// textsUtil.getText("ui.admin.pagemodels.add_new_component.type"),
|
||||
// pageModelsController.getComponentModelTypesDataProvider());
|
||||
componentModelTypeSelect = new ComboBox<>();
|
||||
componentModelTypeSelect.setTextInputAllowed(false);
|
||||
componentModelTypeSelect.setEmptySelectionAllowed(false);
|
||||
componentModelTypeSelect.setDescription(textsUtil
|
||||
.getText("ui.admin.pagemodels.add_new_component.type"));
|
||||
componentModelTypeSelect.setDataProvider(pageModelsController
|
||||
.getComponentModelTypesDataProvider());
|
||||
componentModelTypeSelect
|
||||
.setItemCaptionGenerator(this::generateComponentModelTypeCaption);
|
||||
componentModelTypeSelect.addStyleName(ValoTheme.COMBOBOX_TINY);
|
||||
final Button addComponentModelButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.add_new_component.submit"));
|
||||
addComponentModelButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
addComponentModelButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
addComponentModelButton
|
||||
.addClickListener(this::addComponentButtonClicked);
|
||||
// final Panel componentsPanel = new Panel(
|
||||
// "Components",
|
||||
// new VerticalLayout(new HorizontalLayout(
|
||||
// new FormLayout(componentModelTypeSelect),
|
||||
// addComponentModelButton),
|
||||
// componentsModelGrid));
|
||||
|
||||
final HeaderRow headerRow = componentsModelGrid.prependHeaderRow();
|
||||
final HeaderCell headerCell = headerRow.join(COL_KEY,
|
||||
COL_TYPE,
|
||||
COL_EDIT,
|
||||
COL_DEL);
|
||||
headerCell.setComponent(new HorizontalLayout(componentModelTypeSelect,
|
||||
addComponentModelButton));
|
||||
super.setContent(new VerticalLayout(propertiesSheetLayout,
|
||||
buttonsLayout,
|
||||
componentsModelGrid));
|
||||
// super.setContent(new VerticalLayout(propertiesSheetLayout,
|
||||
// buttonsLayout,
|
||||
// componentsPanel));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addComponentButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final PageModelComponentModel componentModelInfo
|
||||
= componentModelTypeSelect.getValue();
|
||||
|
||||
final String bebopFormClassName = componentModelInfo
|
||||
.editor()
|
||||
.getName();
|
||||
|
||||
final PageModelsController pageModelsController = controller
|
||||
.getPageModelsController();
|
||||
|
||||
final String editorName = bebopFormClassName
|
||||
.replace("com.arsdigita.cms", "org.librecms")
|
||||
.replace("Form", "Editor");
|
||||
|
||||
final Class<? extends AbstractPageModelComponentEditor<?>> editorClass;
|
||||
try {
|
||||
editorClass
|
||||
= (Class<? extends AbstractPageModelComponentEditor<?>>) Class
|
||||
.forName(editorName);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
final Constructor<? extends AbstractPageModelComponentEditor<?>> constructor;
|
||||
try {
|
||||
constructor = editorClass
|
||||
.getDeclaredConstructor(PageModel.class,
|
||||
PageModelComponentModel.class,
|
||||
PageModelComponentEditorController.class);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
final AbstractPageModelComponentEditor<?> editor;
|
||||
try {
|
||||
editor = constructor.newInstance(
|
||||
pageModel,
|
||||
componentModelInfo,
|
||||
pageModelsController.getComponentEditorController());
|
||||
} catch (InstantiationException
|
||||
| IllegalAccessException
|
||||
| InvocationTargetException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
editor.initWidgets();
|
||||
|
||||
editor.setModal(true);
|
||||
editor.setWidth("50%");
|
||||
editor.setHeight("40%");
|
||||
|
||||
UI.getCurrent().addWindow(editor);
|
||||
}
|
||||
|
||||
private void editBasicPropertiesButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final PageModelForm pageModelForm = new PageModelForm(pageModel,
|
||||
application,
|
||||
controller);
|
||||
pageModelForm.setModal(true);
|
||||
pageModelForm.setWidth("40%");
|
||||
pageModelForm.setHeight("30%");
|
||||
|
||||
UI.getCurrent().addWindow(pageModelForm);
|
||||
}
|
||||
|
||||
private String getComponentModelType(final ComponentModel model) {
|
||||
|
||||
return controller
|
||||
.getPageModelsController()
|
||||
.getComponentModelTitle(model.getClass());
|
||||
|
||||
}
|
||||
|
||||
private String generateComponentModelTypeCaption(
|
||||
final PageModelComponentModel item) {
|
||||
|
||||
final GlobalizationHelper globalizationHelper = controller
|
||||
.getGlobalizationHelper();
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(item.descBundle());
|
||||
|
||||
return textsUtil.getText(item.titleKey());
|
||||
}
|
||||
|
||||
private Component buildEditButton(final ComponentModel componentModel) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final Button editButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.components.edit"));
|
||||
editButton.setIcon(VaadinIcons.EDIT);
|
||||
editButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
editButton.addClickListener(event -> editComponentModel(componentModel));
|
||||
|
||||
return editButton;
|
||||
}
|
||||
|
||||
@SuppressWarnings(
|
||||
"unchecked")
|
||||
private void editComponentModel(final ComponentModel componentModel) {
|
||||
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final PageModelsController pageModelsController = controller
|
||||
.getPageModelsController();
|
||||
final ComponentModels componentModels = pageModelsController
|
||||
.getComponentModels();
|
||||
|
||||
final Optional<PageModelComponentModel> componentModelInfo
|
||||
= componentModels
|
||||
.getComponentModelInfo(componentModel.getClass());
|
||||
if (componentModelInfo.isPresent()) {
|
||||
|
||||
final String bebopFormClassName = componentModelInfo
|
||||
.get()
|
||||
.editor()
|
||||
.getName();
|
||||
final String editorName = bebopFormClassName
|
||||
.replace("com.arsdigita.cms", "org.librecms")
|
||||
.replace("Form", "Editor");
|
||||
|
||||
final Class<? extends AbstractPageModelComponentEditor<?>> editorClass;
|
||||
try {
|
||||
editorClass
|
||||
= (Class<? extends AbstractPageModelComponentEditor<?>>) Class
|
||||
.forName(editorName);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
final Constructor<? extends AbstractPageModelComponentEditor<?>> constructor;
|
||||
|
||||
try {
|
||||
constructor = editorClass
|
||||
.getDeclaredConstructor(PageModel.class,
|
||||
componentModelInfo.get().modelClass(),
|
||||
PageModelComponentEditorController.class
|
||||
);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
final AbstractPageModelComponentEditor<?> editor;
|
||||
try {
|
||||
editor = constructor.newInstance(
|
||||
pageModel,
|
||||
componentModel,
|
||||
pageModelsController.getComponentEditorController());
|
||||
} catch (InstantiationException
|
||||
| IllegalAccessException
|
||||
| InvocationTargetException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
editor.initWidgets();
|
||||
|
||||
editor.setModal(true);
|
||||
editor.setWidth("50%");
|
||||
editor.setHeight("40%");
|
||||
|
||||
UI.getCurrent().addWindow(editor);
|
||||
} else {
|
||||
Notification.show(textsUtil
|
||||
.getText("ui.admin.pageModels.no_info_for_component",
|
||||
new String[]{componentModel.getClass().getName()}),
|
||||
Notification.Type.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private Component buildDeleteButton(final ComponentModel componentModel) {
|
||||
|
||||
final PageModelsController pageModelsController = controller
|
||||
.getPageModelsController();
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final Button deleteButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.components.delete"));
|
||||
deleteButton.setIcon(VaadinIcons.MINUS_CIRCLE_O);
|
||||
deleteButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
deleteButton.addClickListener(event -> {
|
||||
|
||||
// ToDo
|
||||
// final ConfirmDialog confirmDialog = new ConfirmDialog(() -> {
|
||||
// pageModelsController.removeComponentModel(pageModel,
|
||||
// componentModel);
|
||||
// return null;
|
||||
// });
|
||||
// confirmDialog.setMessage(textsUtil.getText(
|
||||
// "ui.admin.pagemodels.componentmodels.cols.delete.confirmation"));
|
||||
// confirmDialog.setModal(true);
|
||||
// UI.getCurrent().addWindow(confirmDialog);
|
||||
});
|
||||
|
||||
return deleteButton;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,199 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.l10n.ui.LocalizedStringEditor;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelManager;
|
||||
import org.libreccm.pagemodel.PageModelRepository;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PageModelForm extends Window {
|
||||
|
||||
private static final long serialVersionUID = -8618363472800298648L;
|
||||
|
||||
private final AdminViewController controller;
|
||||
private final CcmApplication application;
|
||||
private PageModel pageModel;
|
||||
|
||||
private TextField nameField;
|
||||
private LocalizedStringEditor titleEditor;
|
||||
private LocalizedStringEditor descriptionEditor;
|
||||
|
||||
public PageModelForm(final AdminViewController controller,
|
||||
final CcmApplication application) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
this.application = application;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public PageModelForm(final PageModel pageModel,
|
||||
final CcmApplication application,
|
||||
final AdminViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.controller = controller;
|
||||
this.application = application;
|
||||
this.pageModel = pageModel;
|
||||
|
||||
addWidgets();
|
||||
|
||||
nameField.setValue(pageModel.getName());
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final GlobalizationHelper globalizationHelper = controller
|
||||
.getGlobalizationHelper();
|
||||
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
nameField = new TextField(textsUtil.getText("ui.admin.pagemodels.name"));
|
||||
nameField.setRequiredIndicatorVisible(true);
|
||||
|
||||
if (pageModel == null) {
|
||||
titleEditor = new LocalizedStringEditor(globalizationHelper);
|
||||
} else {
|
||||
titleEditor = new LocalizedStringEditor(pageModel.getTitle(),
|
||||
globalizationHelper);
|
||||
}
|
||||
// titleEditor.setCaption(textsUtil.getText("ui.admin.pagemodels.title"));
|
||||
titleEditor.setHeight("10em");
|
||||
final Panel titlePanel = new Panel(
|
||||
textsUtil.getText("ui.admin.pagemodels.title"),
|
||||
titleEditor);
|
||||
|
||||
if (pageModel == null) {
|
||||
descriptionEditor = new LocalizedStringEditor(globalizationHelper);
|
||||
} else {
|
||||
descriptionEditor = new LocalizedStringEditor(
|
||||
pageModel.getDescription(), globalizationHelper);
|
||||
}
|
||||
// descriptionEditor
|
||||
// .setCaption(textsUtil.getText("ui.admin.pagemodels.desc"));
|
||||
descriptionEditor.setHeight("10em");
|
||||
final Panel descPanel = new Panel(
|
||||
textsUtil.getText("ui.admin.pagemodels.desc"),
|
||||
descriptionEditor);
|
||||
|
||||
if (pageModel == null) {
|
||||
setCaption(textsUtil.getText("ui.admin.pagemodels.caption.new"));
|
||||
} else {
|
||||
setCaption(textsUtil.getText("ui.admin.pagemodels.caption.edit",
|
||||
new String[]{pageModel.getName()}));
|
||||
}
|
||||
|
||||
final FormLayout formLayout = new FormLayout(nameField);
|
||||
|
||||
final Button saveButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.buttons.save"));
|
||||
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
||||
saveButton.addClickListener(this::saveButtonClicked);
|
||||
final Button cancelButton = new Button(textsUtil
|
||||
.getText("ui.admin.pagemodels.buttons.cancel"));
|
||||
cancelButton.addStyleName(ValoTheme.BUTTON_DANGER);
|
||||
cancelButton.addClickListener(event -> close());
|
||||
final HorizontalLayout buttonsLayout = new HorizontalLayout(saveButton,
|
||||
cancelButton);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout,
|
||||
titlePanel,
|
||||
descPanel,
|
||||
buttonsLayout);
|
||||
layout.setMargin(true);
|
||||
setContent(layout);
|
||||
}
|
||||
|
||||
private void saveButtonClicked(final Button.ClickEvent event) {
|
||||
|
||||
final PageModelsController pageModelsController = controller
|
||||
.getPageModelsController();
|
||||
final PageModelManager pageModelManager = pageModelsController
|
||||
.getPageModelManager();
|
||||
final LocalizedTextsUtil textsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final String name = nameField.getValue();
|
||||
|
||||
if (name == null
|
||||
|| name.isEmpty()
|
||||
|| name.matches("\\s*")) {
|
||||
|
||||
nameField
|
||||
.setComponentError(new UserError(
|
||||
textsUtil.getText("ui.admin.pagemodels.name.error.empty")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pageModel == null) {
|
||||
pageModel = pageModelManager.createPageModel(name, application);
|
||||
final LocalizedString title = titleEditor.getLocalizedString();
|
||||
for (final Map.Entry<Locale, String> entry : title.getValues()
|
||||
.entrySet()) {
|
||||
pageModel.getTitle().addValue(entry.getKey(), entry.getValue());
|
||||
}
|
||||
final LocalizedString desc = descriptionEditor.getLocalizedString();
|
||||
for (final Map.Entry<Locale, String> entry : desc.getValues()
|
||||
.entrySet()) {
|
||||
pageModel.getDescription().addValue(entry.getKey(),
|
||||
entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
pageModel.setName(name);
|
||||
|
||||
final PageModelRepository pageModelRepo = pageModelsController
|
||||
.getPageModelRepo();
|
||||
pageModelRepo.save(pageModel);
|
||||
|
||||
controller
|
||||
.getPageModelsController()
|
||||
.getPageModelsTableDataProvider()
|
||||
.refreshAll();
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.pagemodel.ComponentModel;
|
||||
import org.libreccm.pagemodel.ComponentModelRepository;
|
||||
import org.libreccm.pagemodel.ComponentModels;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelComponentModel;
|
||||
import org.libreccm.pagemodel.PageModelManager;
|
||||
import org.libreccm.pagemodel.PageModelRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PageModelsController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6204724295214879943L;
|
||||
|
||||
@Inject
|
||||
private ComponentModelRepository componentModelRepo;
|
||||
|
||||
@Inject
|
||||
private ComponentModels componentModels;
|
||||
|
||||
@Inject
|
||||
private PageModelComponentEditorController componentEditorController;
|
||||
|
||||
@Inject
|
||||
private PageModelManager pageModelManager;
|
||||
|
||||
@Inject
|
||||
private PageModelRepository pageModelRepo;
|
||||
|
||||
@Inject
|
||||
private PageModelsTableDataProvider pageModelsTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private PageModelComponentModelsTableDataProvider componentModelsTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private PageModelComponentModelTypesDataProvider componentModelTypesDataProvider;
|
||||
|
||||
protected ComponentModels getComponentModels() {
|
||||
return componentModels;
|
||||
}
|
||||
|
||||
protected PageModelComponentEditorController getComponentEditorController() {
|
||||
return componentEditorController;
|
||||
}
|
||||
|
||||
protected PageModelManager getPageModelManager() {
|
||||
return pageModelManager;
|
||||
}
|
||||
|
||||
protected PageModelRepository getPageModelRepo() {
|
||||
return pageModelRepo;
|
||||
}
|
||||
|
||||
protected PageModelsTableDataProvider getPageModelsTableDataProvider() {
|
||||
return pageModelsTableDataProvider;
|
||||
}
|
||||
|
||||
protected PageModelComponentModelsTableDataProvider getComponentModelsTableDataProvider() {
|
||||
return componentModelsTableDataProvider;
|
||||
}
|
||||
|
||||
protected PageModelComponentModelTypesDataProvider getComponentModelTypesDataProvider() {
|
||||
return componentModelTypesDataProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the localised title of the {@link ComponentModel}.
|
||||
*
|
||||
* @param clazz The class of the {@link ComponentModel}.
|
||||
*
|
||||
* @return The localised title of the {@link ComponentModel}.
|
||||
*/
|
||||
protected String getComponentModelTitle(
|
||||
final Class<? extends ComponentModel> clazz) {
|
||||
|
||||
Objects.requireNonNull(clazz);
|
||||
|
||||
final Optional<PageModelComponentModel> info = componentModels
|
||||
.getComponentModelInfo(clazz);
|
||||
|
||||
if (info.isPresent()) {
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(info.get().descBundle());
|
||||
|
||||
return bundle.getString(info.get().titleKey());
|
||||
} else {
|
||||
return clazz.getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void deletePageModel(final long pageModelId) {
|
||||
|
||||
final PageModel pageModel = pageModelRepo
|
||||
.findById(pageModelId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No PageModel with ID %d in the database.",
|
||||
pageModelId)));
|
||||
|
||||
pageModelRepo.delete(pageModel);
|
||||
pageModelsTableDataProvider.refreshAll();
|
||||
}
|
||||
|
||||
// ToDo
|
||||
// @Transactional(Transactional.TxType.REQUIRED)
|
||||
// protected void addComponentModel(final PageModel pageModel,
|
||||
// final ComponentModel componentModel) {
|
||||
//
|
||||
// Objects.requireNonNull(pageModel);
|
||||
// Objects.requireNonNull(componentModel);
|
||||
//
|
||||
// final PageModel toPageModel = pageModelRepo
|
||||
// .findById(pageModel.getPageModelId())
|
||||
// .orElseThrow(() -> new IllegalArgumentException(String
|
||||
// .format("No PageModel with ID %d in the database.",
|
||||
// pageModel.getPageModelId())));
|
||||
//
|
||||
// pageModelManager.addComponentModel(toPageModel, componentModel);
|
||||
// }
|
||||
|
||||
// ToDo
|
||||
// @Transactional(Transactional.TxType.REQUIRED)
|
||||
// protected void removeComponentModel(final PageModel pageModel,
|
||||
// final ComponentModel componentModel) {
|
||||
//
|
||||
// Objects.requireNonNull(pageModel);
|
||||
// Objects.requireNonNull(componentModel);
|
||||
//
|
||||
// final PageModel fromPageModel = pageModelRepo
|
||||
// .findById(pageModel.getPageModelId())
|
||||
// .orElseThrow(() -> new IllegalArgumentException(String
|
||||
// .format("No PageModel with ID %d in the database.",
|
||||
// pageModel.getPageModelId())));
|
||||
//
|
||||
// final ComponentModel theComponentModel = componentModelRepo
|
||||
// .findById(componentModel.getComponentModelId())
|
||||
// .orElseThrow(() -> new IllegalArgumentException(String
|
||||
// .format("No ComponentModel with ID %d in the database.",
|
||||
// componentModel.getComponentModelId())));
|
||||
//
|
||||
// pageModelManager.removeComponentModel(fromPageModel, theComponentModel);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.HorizontalSplitPanel;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Tree;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.ui.ConfirmDialog;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PageModelsTab extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = -1116995764418892909L;
|
||||
|
||||
private static final String COL_NAME = "name";
|
||||
private static final String COL_TITLE = "title";
|
||||
private static final String COL_DESC = "description";
|
||||
private static final String COL_LIVE = "live";
|
||||
private static final String COL_EDIT = "edit";
|
||||
private static final String COL_DELETE = "delete";
|
||||
|
||||
private final Tree<ApplicationTreeNode> applicationTree;
|
||||
private final Grid<PageModelsTableRow> pageModelsGrid;
|
||||
|
||||
protected PageModelsTab(final AdminViewController adminViewController) {
|
||||
|
||||
super();
|
||||
|
||||
applicationTree = new Tree<>(adminViewController
|
||||
.getApplicationTreeDataProvider());
|
||||
applicationTree.setItemCaptionGenerator(ApplicationTreeNode::getTitle);
|
||||
applicationTree.setItemCollapseAllowedProvider(node -> {
|
||||
return !node.getNodeType().equals(ApplicationTreeNodeType.ROOT_NODE);
|
||||
});
|
||||
|
||||
final LocalizedTextsUtil localizedTextsUtil = adminViewController
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
pageModelsGrid = new Grid<>();
|
||||
pageModelsGrid.setDataProvider(adminViewController
|
||||
.getPageModelsController()
|
||||
.getPageModelsTableDataProvider());
|
||||
pageModelsGrid
|
||||
.addColumn(PageModelsTableRow::getName)
|
||||
.setCaption(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.headers.name"))
|
||||
.setId(COL_NAME);
|
||||
pageModelsGrid
|
||||
.addColumn(PageModelsTableRow::getTitle)
|
||||
.setCaption(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.headers.title"))
|
||||
.setId(COL_TITLE);
|
||||
pageModelsGrid
|
||||
.addColumn(PageModelsTableRow::getDescription)
|
||||
.setCaption(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.headers.desc"))
|
||||
.setId(COL_DESC);
|
||||
pageModelsGrid
|
||||
.addColumn(PageModelsTableRow::isPublished)
|
||||
.setCaption(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.headers.islive"))
|
||||
.setId(COL_LIVE);
|
||||
pageModelsGrid
|
||||
.addComponentColumn(row -> buildEditButton(row,
|
||||
adminViewController))
|
||||
.setId(COL_EDIT);
|
||||
pageModelsGrid
|
||||
.addComponentColumn(row -> buildDeleteButton(row,
|
||||
adminViewController))
|
||||
.setId(COL_DELETE);
|
||||
pageModelsGrid.setVisible(false);
|
||||
pageModelsGrid.setWidth("100%");
|
||||
|
||||
final Button addPageModelButton = new Button(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.create_new"));
|
||||
addPageModelButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
addPageModelButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
addPageModelButton.addClickListener(event -> {
|
||||
final CcmApplication application
|
||||
= ((PageModelsTableDataProvider) pageModelsGrid
|
||||
.getDataProvider()).getApplication();
|
||||
final PageModelForm pageModelForm = new PageModelForm(
|
||||
adminViewController, application);
|
||||
pageModelForm.setModal(true);
|
||||
pageModelForm.setWidth("40%");
|
||||
pageModelForm.setHeight("60%");
|
||||
|
||||
UI.getCurrent().addWindow(pageModelForm);
|
||||
});
|
||||
final HeaderRow headerRow = pageModelsGrid.prependHeaderRow();
|
||||
final HeaderCell headerCell = headerRow.join(COL_NAME,
|
||||
COL_TITLE,
|
||||
COL_DESC,
|
||||
COL_LIVE,
|
||||
COL_EDIT,
|
||||
COL_DELETE);
|
||||
headerCell.setComponent(new HorizontalLayout(addPageModelButton));
|
||||
|
||||
final Label placeholder = new Label(localizedTextsUtil.getText(
|
||||
"ui.admin.pagemodels.select_application"));
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(pageModelsGrid,
|
||||
placeholder);
|
||||
layout.setWidth("100%");
|
||||
|
||||
applicationTree.addItemClickListener(event -> {
|
||||
|
||||
final ApplicationTreeNode node = event.getItem();
|
||||
final ApplicationTreeNodeType nodeType = node.getNodeType();
|
||||
|
||||
if (nodeType == ApplicationTreeNodeType.APPLICATION_NODE
|
||||
|| nodeType
|
||||
== ApplicationTreeNodeType.SINGLETON_APPLICATION_NODE) {
|
||||
final PageModelsTableDataProvider dataProvider
|
||||
= (PageModelsTableDataProvider) pageModelsGrid
|
||||
.getDataProvider();
|
||||
dataProvider.setApplicationUuid(node.getNodeId());
|
||||
pageModelsGrid.setVisible(true);
|
||||
placeholder.setVisible(false);
|
||||
} else {
|
||||
pageModelsGrid.setVisible(false);
|
||||
placeholder.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
final VerticalLayout treeLayout = new VerticalLayout(applicationTree);
|
||||
|
||||
final HorizontalSplitPanel panel = new HorizontalSplitPanel(
|
||||
treeLayout, layout);
|
||||
panel.setSplitPosition(20.0f);
|
||||
super.setCompositionRoot(panel);
|
||||
}
|
||||
|
||||
private Component buildEditButton(final PageModelsTableRow row,
|
||||
final AdminViewController controller) {
|
||||
|
||||
final LocalizedTextsUtil localizedTextsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final Button button = new Button(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.edit.label"),
|
||||
VaadinIcons.EDIT);
|
||||
button.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
button.addClickListener(event -> {
|
||||
final PageModel pageModel = controller
|
||||
.getPageModelsController()
|
||||
.getPageModelRepo()
|
||||
.findById(row.getPageModelId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No PageModel with ID %d in the database.",
|
||||
row.getPageModelId())));
|
||||
|
||||
final CcmApplication application
|
||||
= ((PageModelsTableDataProvider) pageModelsGrid
|
||||
.getDataProvider()).getApplication();
|
||||
|
||||
final PageModelDetails pageModelDetails = new PageModelDetails(
|
||||
pageModel, application, controller);
|
||||
pageModelDetails.center();
|
||||
pageModelDetails.setModal(true);
|
||||
pageModelDetails.setWidth("90%");
|
||||
pageModelDetails.setHeight("90%");
|
||||
UI.getCurrent().addWindow(pageModelDetails);
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private Component buildDeleteButton(final PageModelsTableRow row,
|
||||
final AdminViewController controller) {
|
||||
|
||||
final LocalizedTextsUtil localizedTextsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final Button button = new Button(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.table.columns.delete.label"),
|
||||
VaadinIcons.CLOSE_CIRCLE_O);
|
||||
button.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
button.addClickListener(event -> {
|
||||
final ConfirmDialog confirmDialog = new ConfirmDialog(
|
||||
() -> {
|
||||
controller
|
||||
.getPageModelsController()
|
||||
.deletePageModel(row.getPageModelId());
|
||||
|
||||
return null;
|
||||
});
|
||||
confirmDialog.setMessage(localizedTextsUtil
|
||||
.getText("ui.admin.pagemodels.delete.confirm"));
|
||||
confirmDialog.setModal(true);
|
||||
confirmDialog.center();
|
||||
UI.getCurrent().addWindow(confirmDialog);
|
||||
});
|
||||
button.setEnabled(!row.isPublished());
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.pagemodel.PageModel;
|
||||
import org.libreccm.pagemodel.PageModelManager;
|
||||
import org.libreccm.pagemodel.PageModelVersion;
|
||||
import org.libreccm.web.ApplicationRepository;
|
||||
import org.libreccm.web.CcmApplication;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class PageModelsTableDataProvider
|
||||
extends AbstractBackEndDataProvider<PageModelsTableRow, String> {
|
||||
|
||||
private static final long serialVersionUID = 8052894182508842905L;
|
||||
|
||||
@Inject
|
||||
private ApplicationRepository applicationRepo;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private PageModelManager pageModelManager;
|
||||
|
||||
private CcmApplication application;
|
||||
|
||||
public CcmApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public void setApplication(final CcmApplication application) {
|
||||
this.application = application;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void setApplicationUuid(final String uuid) {
|
||||
application = applicationRepo
|
||||
.findByUuid(uuid)
|
||||
.orElseThrow(() -> new UnexpectedErrorException(String
|
||||
.format("No Application with UUID %s in the database.",
|
||||
uuid)));
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
protected Stream<PageModelsTableRow> fetchFromBackEnd(
|
||||
final Query<PageModelsTableRow, String> query) {
|
||||
|
||||
if (application == null) {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<PageModel> criteriaQuery = builder
|
||||
.createQuery(PageModel.class);
|
||||
|
||||
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
|
||||
|
||||
criteriaQuery
|
||||
.where(builder
|
||||
.and(builder.equal(from.get("application"), application),
|
||||
builder.equal(from.get("version"),
|
||||
PageModelVersion.DRAFT)))
|
||||
.orderBy(builder.asc(from.get("name")));
|
||||
// .orderBy(builder.asc(from.get("title")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(this::buildRow);
|
||||
}
|
||||
}
|
||||
|
||||
private PageModelsTableRow buildRow(final PageModel model) {
|
||||
|
||||
final PageModelsTableRow row = new PageModelsTableRow();
|
||||
|
||||
row.setPageModelId(model.getPageModelId());
|
||||
row.setName(model.getName());
|
||||
row.setTitle(globalizationHelper
|
||||
.getValueFromLocalizedString(model.getTitle()));
|
||||
row.setDescription(globalizationHelper
|
||||
.getValueFromLocalizedString(model.getDescription()));
|
||||
row.setPublished(pageModelManager.isLive(model));
|
||||
|
||||
return row;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int sizeInBackEnd(final Query<PageModelsTableRow, String> query) {
|
||||
|
||||
if (application == null) {
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<PageModel> from = criteriaQuery.from(PageModel.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
|
||||
criteriaQuery
|
||||
.where(builder
|
||||
.and(builder.equal(from.get("application"), application),
|
||||
builder.equal(from.get("version"),
|
||||
PageModelVersion.DRAFT)));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class PageModelsTableRow implements Serializable,
|
||||
Comparable<PageModelsTableRow> {
|
||||
|
||||
private static final long serialVersionUID = -6995542858134206603L;
|
||||
|
||||
private long pageModelId;
|
||||
private String name;
|
||||
private String title;
|
||||
private String description;
|
||||
private boolean published;
|
||||
|
||||
public long getPageModelId() {
|
||||
return pageModelId;
|
||||
}
|
||||
|
||||
public void setPageModelId(final long pageModelId) {
|
||||
this.pageModelId = pageModelId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
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 boolean isPublished() {
|
||||
return published;
|
||||
}
|
||||
|
||||
public void setPublished(final boolean published) {
|
||||
this.published = published;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 17 * hash + (int) (pageModelId ^ (pageModelId >>> 32));
|
||||
hash = 17 * hash + Objects.hashCode(name);
|
||||
hash = 17 * hash + Objects.hashCode(title);
|
||||
hash = 17 * hash + Objects.hashCode(description);
|
||||
hash = 17 * hash + (published ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof PageModelsTableRow)) {
|
||||
return false;
|
||||
}
|
||||
final PageModelsTableRow other = (PageModelsTableRow) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pageModelId != other.getPageModelId()) {
|
||||
return false;
|
||||
}
|
||||
if (published != other.isPublished()) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(name, other.getName())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(title, other.getTitle())) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(description, other.getDescription());
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof PageModelsTableRow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final PageModelsTableRow other) {
|
||||
|
||||
int result = title.compareTo(other.getTitle());
|
||||
|
||||
if (result == 0) {
|
||||
result = name.compareTo(other.getName());
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
result = Boolean.compare(published, other.isPublished());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
public String toString(final String data) {
|
||||
|
||||
return String.format("%s{ "
|
||||
+ "pageModelId = %d, "
|
||||
+ "name = \"%s\", "
|
||||
+ "published = %b, "
|
||||
+ "title = \"%s\", "
|
||||
+ "description = \"%s\"%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
pageModelId,
|
||||
name,
|
||||
published,
|
||||
title,
|
||||
description,
|
||||
data);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Party;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PartySelectionAction {
|
||||
|
||||
void action(Set<Party> selectedParties);
|
||||
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Party;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class PartySelector extends Window {
|
||||
|
||||
private static final long serialVersionUID = 6915710902238111484L;
|
||||
|
||||
private static final String COL_PARTY_NAME = "partyname";
|
||||
|
||||
protected PartySelector(final String caption,
|
||||
final String actionLabel,
|
||||
final PartySelectorDataProvider dataProvider,
|
||||
final List<Party> excludedParties,
|
||||
final PartySelectionAction action) {
|
||||
|
||||
addWidgets(caption, actionLabel, dataProvider, excludedParties, action);
|
||||
}
|
||||
|
||||
private void addWidgets(final String caption,
|
||||
final String actionLabel,
|
||||
final PartySelectorDataProvider dataProvider,
|
||||
final List<Party> excludedParties,
|
||||
final PartySelectionAction action) {
|
||||
|
||||
setCaption(caption);
|
||||
|
||||
final Grid<Party> partiesGrid = new Grid<>();
|
||||
partiesGrid
|
||||
.addColumn(Party::getName)
|
||||
.setId(COL_PARTY_NAME)
|
||||
.setCaption("Party name");
|
||||
|
||||
partiesGrid.setSelectionMode(Grid.SelectionMode.MULTI);
|
||||
partiesGrid.setWidth("100%");
|
||||
|
||||
final Button actionButton = new Button(actionLabel);
|
||||
actionButton.addClickListener(event -> {
|
||||
action.action(partiesGrid.getSelectedItems());
|
||||
close();
|
||||
});
|
||||
actionButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
actionButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final Button clearButton = new Button("Clear selection");
|
||||
clearButton.addClickListener(event -> {
|
||||
partiesGrid.getSelectionModel().deselectAll();
|
||||
});
|
||||
clearButton.setIcon(VaadinIcons.BACKSPACE);
|
||||
clearButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final HeaderRow actions = partiesGrid.prependHeaderRow();
|
||||
final HeaderCell actionsCell = actions.getCell(COL_PARTY_NAME);
|
||||
actionsCell.setComponent(new HorizontalLayout(actionButton,
|
||||
clearButton));
|
||||
|
||||
dataProvider.setExcludedParties(excludedParties);
|
||||
partiesGrid.setDataProvider(dataProvider);
|
||||
|
||||
setContent(partiesGrid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Party;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class PartySelectorDataProvider extends AbstractDataProvider<Party, String> {
|
||||
|
||||
private static final long serialVersionUID = -3271211882810011968L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private String partyNameFilter;
|
||||
|
||||
private List<Party> excludedParties;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Party, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<Party> from = criteriaQuery.from(Party.class);
|
||||
criteriaQuery
|
||||
.select(builder.count(from))
|
||||
.distinct(true);
|
||||
|
||||
if (partyNameFilter != null && !partyNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", partyNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedParties != null && !excludedParties.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedParties)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Party> fetch(final Query<Party, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Party> criteriaQuery = builder
|
||||
.createQuery(Party.class);
|
||||
final Root<Party> from = criteriaQuery.from(Party.class);
|
||||
criteriaQuery.distinct(true);
|
||||
|
||||
if (partyNameFilter != null && !partyNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", partyNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedParties != null && !excludedParties.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedParties)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
public void setPartyNameFilter(final String partyNameFilter) {
|
||||
this.partyNameFilter = partyNameFilter;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
public void setExcludedParties(final List<Party> excludedParties) {
|
||||
this.excludedParties = excludedParties;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Party;
|
||||
import org.libreccm.security.PartyRepository;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class RoleDetails extends Window {
|
||||
|
||||
private static final long serialVersionUID = 8109931561947913438L;
|
||||
|
||||
private static final String COL_MEMBER_NAME = "partyname";
|
||||
private static final String COL_MEMBER_REMOVE = "member_remove";
|
||||
|
||||
private final Role role;
|
||||
private final RolesController controller;
|
||||
|
||||
protected RoleDetails(final Role role,
|
||||
final RolesController controller) {
|
||||
|
||||
super(String.format("Details of role %s", role.getName()));
|
||||
|
||||
this.role = role;
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final Label roleName = new Label(role.getName());
|
||||
roleName.setCaption(bundle
|
||||
.getString("ui.admin.role_edit.rolename.label"));
|
||||
|
||||
//description
|
||||
final Label roleDescription = new Label(role.getName());
|
||||
roleDescription.setCaption(bundle
|
||||
.getString("ui.admin.role_edit.description.label"));
|
||||
|
||||
final FormLayout formLayout = new FormLayout(roleName,
|
||||
roleDescription);
|
||||
|
||||
final Button editButton = new Button(
|
||||
bundle.getString("ui.admin.roles.table.edit"),
|
||||
event -> {
|
||||
final RoleEditor editor = new RoleEditor(
|
||||
role,
|
||||
controller.getRoleRepository());
|
||||
editor.center();
|
||||
UI.getCurrent().addWindow(editor);
|
||||
});
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout,
|
||||
editButton);
|
||||
|
||||
final RolePartiesController partiesController = controller
|
||||
.getPartiesController();
|
||||
|
||||
final Grid<Party> partiesGrid = new Grid<>();
|
||||
partiesGrid
|
||||
.addColumn(Party::getName)
|
||||
.setId(COL_MEMBER_NAME)
|
||||
.setCaption("Name");
|
||||
partiesGrid
|
||||
.addComponentColumn(party -> {
|
||||
final Button removeButton = new Button(
|
||||
bundle.getString("ui.role.parties.remove"),
|
||||
VaadinIcons.CLOSE_CIRCLE_O);
|
||||
removeButton.addClickListener(event -> {
|
||||
partiesController.removePartyFromRole(party, role);
|
||||
partiesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
removeButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return removeButton;
|
||||
})
|
||||
.setId(COL_MEMBER_REMOVE);
|
||||
|
||||
partiesGrid.setWidth("100%");
|
||||
|
||||
final PartyRepository partyRepo = controller.getPartyRepository();
|
||||
|
||||
final HeaderRow partiesGridHeader = partiesGrid.prependHeaderRow();
|
||||
final Button addPartyButton = new Button("Add member");
|
||||
addPartyButton.setIcon(VaadinIcons.PLUS);
|
||||
addPartyButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
addPartyButton.addClickListener(event -> {
|
||||
final PartySelector partySelector = new PartySelector(
|
||||
"Select parties to add to role",
|
||||
"Add selected parties to role",
|
||||
controller.getPartySelectorDataProvider(),
|
||||
partyRepo.findByRole(role),
|
||||
selectedParties -> {
|
||||
selectedParties.forEach(party -> {
|
||||
partiesController.assignPartyToRole(party, role);
|
||||
});
|
||||
partiesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
partySelector.addCloseListener(closeEvent -> {
|
||||
partiesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
partySelector.center();
|
||||
partySelector.setWidth("80%");
|
||||
UI.getCurrent().addWindow(partySelector);
|
||||
});
|
||||
final HeaderCell partiesGridHeaderCell = partiesGridHeader
|
||||
.join(COL_MEMBER_NAME, COL_MEMBER_REMOVE);
|
||||
partiesGridHeaderCell
|
||||
.setComponent(new HorizontalLayout(addPartyButton));
|
||||
|
||||
final RolePartiesDataProvider partiesDataProvider = controller
|
||||
.getRolePartiesDataProvider();
|
||||
partiesDataProvider.setRole(role);
|
||||
partiesGrid.setDataProvider(partiesDataProvider);
|
||||
|
||||
final TabSheet tabs = new TabSheet();
|
||||
tabs.addTab(layout, "Details");
|
||||
tabs.addTab(partiesGrid, "Members");
|
||||
|
||||
setContent(tabs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.TextArea;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class RoleEditor extends Window {
|
||||
|
||||
private static final long serialVersionUID = -2982855646090602847L;
|
||||
|
||||
private final Role role;
|
||||
private final RoleRepository roleRepo;
|
||||
|
||||
private boolean dataHasChanged = false;
|
||||
|
||||
private TextField roleName;
|
||||
private TextArea roleDescription;
|
||||
|
||||
protected RoleEditor(final RoleRepository roleRepo) {
|
||||
|
||||
super("Create new role");
|
||||
|
||||
role = null;
|
||||
this.roleRepo = roleRepo;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public RoleEditor(final Role role,
|
||||
final RoleRepository roleRepo) {
|
||||
|
||||
super(String.format("Edit role %s", role.getName()));
|
||||
|
||||
this.role = role;
|
||||
this.roleRepo = roleRepo;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final DataHasChangedListener dataHasChangedListener
|
||||
= new DataHasChangedListener();
|
||||
|
||||
roleName = new TextField(bundle
|
||||
.getString("ui.admin.role_edit.rolename.label"));
|
||||
roleName.setRequiredIndicatorVisible(true);
|
||||
roleName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
roleDescription = new TextArea(bundle
|
||||
.getString("ui.admin.role_edit.roledescription.label"));
|
||||
roleDescription.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
final Button submit = new Button();
|
||||
if (role == null) {
|
||||
submit.setCaption(bundle
|
||||
.getString("ui.admin.role.createpanel.header"));
|
||||
} else {
|
||||
submit.setCaption(bundle.getString("ui.admin.save"));
|
||||
}
|
||||
submit.addClickListener(event -> saveRole());
|
||||
|
||||
final Button cancel = new Button(bundle.getString("ui.admin.cancel"));
|
||||
cancel.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttons = new HorizontalLayout(submit, cancel);
|
||||
|
||||
final FormLayout formLayout = new FormLayout(roleName,
|
||||
roleDescription);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout, buttons);
|
||||
|
||||
// final Panel panel = new Panel(layout);
|
||||
// if (role == null) {
|
||||
// panel.setCaption(bundle
|
||||
// .getString("ui.admin.group.createpanel.header"));
|
||||
// } else {
|
||||
// panel.setCaption(bundle
|
||||
// .getString("ui.admin.group_details.edit"));
|
||||
// }
|
||||
if (role != null) {
|
||||
roleName.setValue(role.getName());
|
||||
final String description = role
|
||||
.getDescription()
|
||||
.getValue(UI.getCurrent().getLocale());
|
||||
if (description == null) {
|
||||
roleDescription.setValue("");
|
||||
} else {
|
||||
roleDescription.setValue(role
|
||||
.getDescription()
|
||||
.getValue(UI.getCurrent().getLocale()));
|
||||
}
|
||||
}
|
||||
|
||||
setContent(layout);
|
||||
|
||||
dataHasChanged = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
if (dataHasChanged) {
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final ConfirmDiscardDialog dialog = new ConfirmDiscardDialog(
|
||||
this,
|
||||
bundle.getString("ui.admin.role_edit.discard_confirm"));
|
||||
dialog.setModal(true);
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
} else {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveRole() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
if (roleName.getValue() == null
|
||||
|| roleName.getValue().trim().isEmpty()) {
|
||||
|
||||
roleName.setComponentError(new UserError(
|
||||
bundle.getString("ui.admin.role_edit.rolename.error.notempty")));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Role currentRole;
|
||||
if (role == null) {
|
||||
currentRole = new Role();
|
||||
|
||||
} else {
|
||||
currentRole = role;
|
||||
}
|
||||
|
||||
currentRole.setName(roleName.getValue());
|
||||
if (roleDescription.getValue() != null
|
||||
&& !roleDescription.getValue().trim().isEmpty()) {
|
||||
currentRole.getDescription().addValue(UI.getCurrent().getLocale(),
|
||||
roleDescription.getValue());
|
||||
}
|
||||
|
||||
roleRepo.save(currentRole);
|
||||
|
||||
dataHasChanged = false;
|
||||
close();
|
||||
}
|
||||
|
||||
private class DataHasChangedListener
|
||||
implements HasValue.ValueChangeListener<String> {
|
||||
|
||||
private static final long serialVersionUID = -1410903365203533072L;
|
||||
|
||||
@Override
|
||||
public void valueChange(final HasValue.ValueChangeEvent<String> event) {
|
||||
dataHasChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
|
||||
import org.libreccm.security.Party;
|
||||
import org.libreccm.security.PartyRepository;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleManager;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class RolePartiesController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4256699834158368925L;
|
||||
|
||||
@Inject
|
||||
private PartyRepository partyRepo;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepo;
|
||||
|
||||
@Inject
|
||||
private RoleManager roleManager;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignPartiesToRole(final Set<Party> parties,
|
||||
final Role role) {
|
||||
|
||||
parties.forEach(party -> assignPartyToRole(party, role));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignPartyToRole(final Party party, final Role role) {
|
||||
|
||||
final Party theParty = partyRepo
|
||||
.findById(party.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Party with ID %d in the database.",
|
||||
party.getPartyId())));
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
roleManager.assignRoleToParty(theRole, theParty);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void removePartyFromRole(final Party party, final Role role) {
|
||||
|
||||
final Party theParty = partyRepo
|
||||
.findById(party.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Party with ID %d in the database.",
|
||||
party.getPartyId())));
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
roleManager.removeRoleFromParty(theRole, theParty);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Party;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleMembership;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class RolePartiesDataProvider extends AbstractDataProvider<Party, String> {
|
||||
|
||||
private static final long serialVersionUID = -2770993810657270285L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private Role role;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<Party, String> query) {
|
||||
|
||||
Objects.requireNonNull(role,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setRole(Role) before calling "
|
||||
+ "the count method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<RoleMembership> from = criteriaQuery
|
||||
.from(RoleMembership.class);
|
||||
|
||||
criteriaQuery
|
||||
.select(builder.count(from))
|
||||
.where(builder.equal(from.get("role"), role));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Party> fetch(final Query<Party, String> query) {
|
||||
|
||||
Objects.requireNonNull(role,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setRole(Role) before calling "
|
||||
+ "the count method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<RoleMembership> criteriaQuery =builder
|
||||
.createQuery(RoleMembership.class);
|
||||
final Root<RoleMembership> from = criteriaQuery
|
||||
.from(RoleMembership.class);
|
||||
final Join<?, ?> join = from.join("role");
|
||||
criteriaQuery
|
||||
.where(builder.equal(from.get("role"), role))
|
||||
.orderBy(builder.asc(join.get("name")));
|
||||
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(RoleMembership::getMember);
|
||||
}
|
||||
|
||||
public void setRole(final Role role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Role;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RoleSelectionAction {
|
||||
|
||||
void action(Set<Role> selectedRoles);
|
||||
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Role;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class RoleSelector extends Window {
|
||||
|
||||
private static final long serialVersionUID = -6893510634359633368L;
|
||||
|
||||
private static final String COL_NAME = "rolename";
|
||||
|
||||
protected RoleSelector(final String caption,
|
||||
final String actionLabel,
|
||||
final RoleSelectorDataProvider dataProvider,
|
||||
final List<Role> excludedRoles,
|
||||
final RoleSelectionAction action) {
|
||||
|
||||
addWidgets(caption, actionLabel, dataProvider, excludedRoles, action);
|
||||
}
|
||||
|
||||
private void addWidgets(final String caption,
|
||||
final String actionLabel,
|
||||
final RoleSelectorDataProvider dataProvider,
|
||||
final List<Role> excludedRoles,
|
||||
final RoleSelectionAction action) {
|
||||
|
||||
setCaption(caption);
|
||||
|
||||
final Grid<Role> rolesGrid = new Grid<>();
|
||||
rolesGrid
|
||||
.addColumn(Role::getName)
|
||||
.setId(COL_NAME)
|
||||
.setCaption("Role");
|
||||
|
||||
rolesGrid.setSelectionMode(Grid.SelectionMode.MULTI);
|
||||
rolesGrid.setWidth("100%");
|
||||
|
||||
final Button actionButton = new Button(actionLabel);
|
||||
actionButton.addClickListener(event -> {
|
||||
action.action(rolesGrid.getSelectedItems());
|
||||
close();
|
||||
});
|
||||
actionButton.setIcon(VaadinIcons.PLUS_CIRCLE_O);
|
||||
actionButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final Button clearButton = new Button("Clear selection");
|
||||
clearButton.addClickListener(event -> {
|
||||
rolesGrid.getSelectionModel().deselectAll();
|
||||
});
|
||||
clearButton.setIcon(VaadinIcons.BACKSPACE);
|
||||
clearButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
final HeaderRow actions = rolesGrid.prependHeaderRow();
|
||||
final HeaderCell actionsCell = actions.getCell(COL_NAME);
|
||||
actionsCell.setComponent(new HorizontalLayout(actionButton,
|
||||
clearButton));
|
||||
|
||||
|
||||
dataProvider.setExcludedRoles(excludedRoles);
|
||||
rolesGrid.setDataProvider(dataProvider);
|
||||
|
||||
setContent(rolesGrid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Role;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class RoleSelectorDataProvider extends AbstractDataProvider<Role, String> {
|
||||
|
||||
private static final long serialVersionUID = 6142912046579055420L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private String roleNameFilter;
|
||||
|
||||
private List<Role> excludedRoles;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Role, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
final Root<Role> from = criteriaQuery.from(Role.class);
|
||||
criteriaQuery.select(builder.count(from));
|
||||
criteriaQuery.distinct(true);
|
||||
|
||||
if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", roleNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedRoles != null && !excludedRoles.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedRoles)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Role> fetch(final Query<Role, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Role> criteriaQuery = builder
|
||||
.createQuery(Role.class);
|
||||
final Root<Role> from = criteriaQuery.from(Role.class);
|
||||
criteriaQuery.distinct(true);
|
||||
|
||||
if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", roleNameFilter)));
|
||||
}
|
||||
|
||||
if (excludedRoles != null && !excludedRoles.isEmpty()) {
|
||||
criteriaQuery.where(builder.not(from.in(excludedRoles)));
|
||||
}
|
||||
|
||||
criteriaQuery.orderBy(builder.asc(from.get("name")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
public void setRoleNameFilter(final String roleNameFilter) {
|
||||
this.roleNameFilter = roleNameFilter;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
public void setExcludedRoles(final List<Role> excludedRoles) {
|
||||
this.excludedRoles = new ArrayList<>(excludedRoles);
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.PartyRepository;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class RolesController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 429870757932223171L;
|
||||
|
||||
@Inject
|
||||
private RolePartiesController partiesController;
|
||||
|
||||
@Inject
|
||||
private PartyRepository partyRepository;
|
||||
|
||||
@Inject
|
||||
private PartySelectorDataProvider partySelectorDataProvider;
|
||||
|
||||
@Inject
|
||||
private RolePartiesDataProvider rolePartiesDataProvider;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepository;
|
||||
|
||||
protected RolePartiesController getPartiesController() {
|
||||
return partiesController;
|
||||
}
|
||||
|
||||
protected PartyRepository getPartyRepository() {
|
||||
return partyRepository;
|
||||
}
|
||||
|
||||
protected PartySelectorDataProvider getPartySelectorDataProvider() {
|
||||
return partySelectorDataProvider;
|
||||
}
|
||||
|
||||
protected RoleRepository getRoleRepository() {
|
||||
return roleRepository;
|
||||
}
|
||||
|
||||
protected RolePartiesDataProvider getRolePartiesDataProvider() {
|
||||
return rolePartiesDataProvider;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class RolesTable extends Grid<Role> {
|
||||
|
||||
private static final long serialVersionUID = 8298191390811634176L;
|
||||
|
||||
private final static String COL_NAME = "name";
|
||||
private final static String COL_DESCRIPTION = "description";
|
||||
private final static String COL_EDIT = "edit";
|
||||
private final static String COL_DELETE = "delete";
|
||||
|
||||
private final TextField roleNameFilter;
|
||||
private final Button clearFiltersButton;
|
||||
private final Button createRoleButton;
|
||||
|
||||
protected RolesTable(final UsersGroupsRolesController controller) {
|
||||
|
||||
super();
|
||||
|
||||
super.setDataProvider(controller.getRolesTableDataProvider());
|
||||
|
||||
final LocalizedTextsUtil adminTextUtils = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
addColumn(Role::getName)
|
||||
.setId(COL_NAME)
|
||||
.setCaption(adminTextUtils.getText("ui.admin.roles.table.name"));
|
||||
addColumn(role -> {
|
||||
if (role.getDescription().hasValue(UI.getCurrent().getLocale())) {
|
||||
return role.getDescription()
|
||||
.getValue(UI.getCurrent().getLocale());
|
||||
} else {
|
||||
final Optional<Locale> locale = role
|
||||
.getDescription()
|
||||
.getAvailableLocales()
|
||||
.stream()
|
||||
.sorted((locale1, locale2) -> {
|
||||
return locale1.toString().compareTo(locale2.toString());
|
||||
})
|
||||
.findFirst();
|
||||
if (locale.isPresent()) {
|
||||
return role.getDescription().getValue(locale.get());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
})
|
||||
.setId(COL_DESCRIPTION)
|
||||
.setCaption(adminTextUtils.getText(
|
||||
"ui.admin.roles.table.description"));
|
||||
addComponentColumn(role -> {
|
||||
final Button editButton = new Button(
|
||||
adminTextUtils.getText("ui.admin.roles.table.edit"),
|
||||
VaadinIcons.EDIT);
|
||||
editButton.addClickListener(event -> {
|
||||
final RoleDetails roleDetails = new RoleDetails(
|
||||
role,
|
||||
controller.getRolesController());
|
||||
roleDetails.setModal(true);
|
||||
roleDetails.center();
|
||||
roleDetails.setWidth("80%");
|
||||
UI.getCurrent().addWindow(roleDetails);
|
||||
});
|
||||
editButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
return editButton;
|
||||
})
|
||||
.setId(COL_EDIT);
|
||||
addColumn(role -> {
|
||||
final Button deleteButton = new Button(
|
||||
adminTextUtils.getText("ui.admin.roles.table.delete"),
|
||||
VaadinIcons.MINUS_CIRCLE_O);
|
||||
deleteButton.addClickListener(event -> {
|
||||
final ConfirmDeleteDialog dialog
|
||||
= new ConfirmDeleteDialog(
|
||||
role,
|
||||
controller.getRoleRepository(),
|
||||
adminTextUtils);
|
||||
dialog.setModal(true);
|
||||
dialog.center();
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
});
|
||||
deleteButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return deleteButton;
|
||||
})
|
||||
.setId(COL_DELETE);
|
||||
|
||||
final HeaderRow filterRow = appendHeaderRow();
|
||||
final HeaderCell GroupNameFilterCell = filterRow.getCell(COL_NAME);
|
||||
roleNameFilter = new TextField();
|
||||
roleNameFilter.setPlaceholder(adminTextUtils
|
||||
.getText("ui.admin.users.table.filter.rolename.placeholder"));
|
||||
roleNameFilter.setDescription(adminTextUtils
|
||||
.getText("ui.admin.users.table.filter.rolename.description"));
|
||||
roleNameFilter.addStyleName(ValoTheme.TEXTFIELD_TINY);
|
||||
roleNameFilter
|
||||
.addValueChangeListener(event -> {
|
||||
((RolesTableDataProvider) getDataProvider())
|
||||
.setRoleNameFilter(event.getValue().toLowerCase());
|
||||
});
|
||||
GroupNameFilterCell.setComponent(roleNameFilter);
|
||||
|
||||
final HeaderRow actionsRow = prependHeaderRow();
|
||||
final HeaderCell actionsCell = actionsRow.join(COL_NAME,
|
||||
COL_DESCRIPTION,
|
||||
COL_EDIT,
|
||||
COL_DELETE);
|
||||
clearFiltersButton = new Button(adminTextUtils
|
||||
.getText("ui.admin.users.table.filter.clear"));
|
||||
clearFiltersButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
clearFiltersButton.setIcon(VaadinIcons.BACKSPACE);
|
||||
clearFiltersButton.addClickListener(event -> {
|
||||
roleNameFilter.setValue("");
|
||||
});
|
||||
|
||||
createRoleButton = new Button("New role");
|
||||
createRoleButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
createRoleButton.setIcon(VaadinIcons.PLUS);
|
||||
createRoleButton.addClickListener(event -> {
|
||||
final RoleEditor roleEditor = new RoleEditor(
|
||||
controller.getRoleRepository());
|
||||
roleEditor.center();
|
||||
roleEditor.addCloseListener(closeEvent -> {
|
||||
getDataProvider().refreshAll();
|
||||
});
|
||||
UI.getCurrent().addWindow(roleEditor);
|
||||
});
|
||||
final HorizontalLayout actionsLayout = new HorizontalLayout(
|
||||
clearFiltersButton,
|
||||
createRoleButton);
|
||||
actionsCell.setComponent(actionsLayout);
|
||||
}
|
||||
|
||||
private class ConfirmDeleteDialog extends Window {
|
||||
|
||||
private static final long serialVersionUID = -1315311220464298282L;
|
||||
|
||||
private final Role role;
|
||||
private final RoleRepository roleRepo;
|
||||
|
||||
public ConfirmDeleteDialog(final Role role,
|
||||
final RoleRepository roleRepo,
|
||||
final LocalizedTextsUtil adminBundle) {
|
||||
this.role = role;
|
||||
this.roleRepo = roleRepo;
|
||||
|
||||
final MessageFormat messageFormat = new MessageFormat(
|
||||
adminBundle.getText("ui.admin.roles.delete.confirm"));
|
||||
|
||||
final Label text = new Label(messageFormat
|
||||
.format(new Object[]{role.getName()}));
|
||||
|
||||
final Button yesButton
|
||||
= new Button(adminBundle.getText("ui.admin.yes"));
|
||||
yesButton.addClickListener(event -> deleteRole());
|
||||
|
||||
final Button noButton = new Button(adminBundle
|
||||
.getText("ui.admin.no"));
|
||||
noButton.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttons = new HorizontalLayout(yesButton,
|
||||
noButton);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(text, buttons);
|
||||
|
||||
super.setContent(layout);
|
||||
}
|
||||
|
||||
private void deleteRole() {
|
||||
roleRepo.delete(role);
|
||||
getDataProvider().refreshAll();
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Role;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class RolesTableDataProvider extends AbstractDataProvider<Role, String> {
|
||||
|
||||
private static final long serialVersionUID = 6305886670608199133L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private String roleNameFilter;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Role, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> criteriaQuery = builder.createQuery(Long.class);
|
||||
final Root<Role> from = criteriaQuery.from(Role.class);
|
||||
|
||||
criteriaQuery = criteriaQuery.select(builder.count(from));
|
||||
|
||||
if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", roleNameFilter)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Role> fetch(final Query<Role, String> query) {
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Role> criteriaQuery = builder.createQuery(Role.class);
|
||||
final Root<Role> from = criteriaQuery.from(Role.class);
|
||||
|
||||
if (roleNameFilter != null && !roleNameFilter.trim().isEmpty()) {
|
||||
criteriaQuery
|
||||
.where(builder.like(builder.lower(from.get("name")),
|
||||
String.format("%s%%", roleNameFilter)));
|
||||
}
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream();
|
||||
}
|
||||
|
||||
public void setRoleNameFilter(final String roleNameFilter) {
|
||||
this.roleNameFilter = roleNameFilter;
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.NativeSelect;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.libreccm.theming.ThemeInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class SiteEditor extends Window {
|
||||
|
||||
private static final long serialVersionUID = 7016158691791408762L;
|
||||
|
||||
private final Site site;
|
||||
private final AdminViewController controller;
|
||||
|
||||
private final boolean isNewSite;
|
||||
private boolean dataHasChanged = false;
|
||||
|
||||
public SiteEditor(final AdminViewController controller) {
|
||||
super();
|
||||
|
||||
this.site = new Site();
|
||||
isNewSite = true;
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public SiteEditor(final Site site, final AdminViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
this.site = site;
|
||||
isNewSite = false;
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final LocalizedTextsUtil adminTextsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
if (site == null) {
|
||||
setCaption(adminTextsUtil.getText("ui.admin.sites.create_new"));
|
||||
} else {
|
||||
setCaption(adminTextsUtil.getText("ui.admin.sites.edit"));
|
||||
}
|
||||
|
||||
final TextField domainOfSiteField = new TextField(
|
||||
adminTextsUtil.getText("ui.admin.sites.domain_of_site"));
|
||||
domainOfSiteField.setValue(site.getDomainOfSite());
|
||||
domainOfSiteField.addValueChangeListener(event -> {
|
||||
dataHasChanged = true;
|
||||
});
|
||||
|
||||
final CheckBox isDefaultSiteCheckBox = new CheckBox(
|
||||
adminTextsUtil.getText("ui.admin.sites.is_default_site"));
|
||||
isDefaultSiteCheckBox.setValue(site.isDefaultSite());
|
||||
isDefaultSiteCheckBox.addValueChangeListener(event -> {
|
||||
dataHasChanged = true;
|
||||
});
|
||||
|
||||
final List<String> themes = controller
|
||||
.getSitesController()
|
||||
.getThemes()
|
||||
.getAvailableThemes()
|
||||
.stream()
|
||||
.map(ThemeInfo::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final NativeSelect<String> defaultThemeSelect = new NativeSelect<>(
|
||||
adminTextsUtil.getText("ui.admin.sites.default_theme"), themes);
|
||||
defaultThemeSelect.setValue(site.getDefaultTheme());
|
||||
defaultThemeSelect.addValueChangeListener(event -> {
|
||||
dataHasChanged = true;
|
||||
});
|
||||
|
||||
final Button saveButton = new Button();
|
||||
if (site == null) {
|
||||
saveButton.setCaption(adminTextsUtil.getText(
|
||||
"ui.admin.sites.buttons.save.create"));
|
||||
} else {
|
||||
saveButton.setCaption(adminTextsUtil.getText(
|
||||
"ui.admin.sites.buttons.save.changed"));
|
||||
}
|
||||
saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
||||
saveButton.addClickListener(event -> {
|
||||
if (dataHasChanged) {
|
||||
|
||||
final String domainOfSite = domainOfSiteField.getValue();
|
||||
if (domainOfSite == null
|
||||
|| domainOfSite.isEmpty()
|
||||
|| domainOfSite.matches("\\s*")) {
|
||||
|
||||
domainOfSiteField.setComponentError(new UserError(
|
||||
adminTextsUtil.getText(
|
||||
"ui.admin.sites.domain_of_site.error.empty")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!controller.getSitesController().isUnique(domainOfSite)
|
||||
&& (!Objects.equals(site.getDomainOfSite(),
|
||||
domainOfSiteField.getValue()))) {
|
||||
domainOfSiteField.setComponentError(new UserError(
|
||||
adminTextsUtil.getText(
|
||||
"ui.admin.sites.domain_of_site.error.not_unique")));
|
||||
return;
|
||||
}
|
||||
|
||||
site.setDomainOfSite(domainOfSite);
|
||||
site.setDefaultSite(isDefaultSiteCheckBox.getValue());
|
||||
site.setDefaultTheme(defaultThemeSelect.getValue());
|
||||
|
||||
controller
|
||||
.getSitesController()
|
||||
.getSiteRepository()
|
||||
.save(site);
|
||||
controller
|
||||
.getSitesController()
|
||||
.getSitesTableDataProvider()
|
||||
.refreshAll();
|
||||
close();
|
||||
if (isNewSite) {
|
||||
Notification.show(adminTextsUtil
|
||||
.getText("ui.admin.sites.created_new_site",
|
||||
new Object[]{domainOfSite}),
|
||||
Notification.Type.TRAY_NOTIFICATION);
|
||||
} else {
|
||||
Notification.show(adminTextsUtil
|
||||
.getText("ui.admin.sites.save_changes",
|
||||
new Object[]{domainOfSite}),
|
||||
Notification.Type.TRAY_NOTIFICATION);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Button cancelButton = new Button(adminTextsUtil
|
||||
.getText("ui.admin.sites.buttons.cancel"));
|
||||
cancelButton.addClickListener(event -> {
|
||||
close();
|
||||
});
|
||||
|
||||
super.setContent(new VerticalLayout(
|
||||
new FormLayout(domainOfSiteField,
|
||||
isDefaultSiteCheckBox,
|
||||
defaultThemeSelect),
|
||||
new HorizontalLayout(saveButton, cancelButton)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.libreccm.sites.SiteRepository;
|
||||
import org.libreccm.theming.Themes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class SitesController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 112502641827852807L;
|
||||
|
||||
@Inject
|
||||
private SiteRepository siteRepository;
|
||||
|
||||
@Inject
|
||||
private SitesTableDataProvider sitesTableDataProvider;
|
||||
|
||||
@Inject
|
||||
private Themes themes;
|
||||
|
||||
protected SitesTableDataProvider getSitesTableDataProvider() {
|
||||
return sitesTableDataProvider;
|
||||
}
|
||||
|
||||
protected Themes getThemes() {
|
||||
return themes;
|
||||
}
|
||||
|
||||
protected SiteRepository getSiteRepository() {
|
||||
return siteRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there no site with the provided domain.
|
||||
*
|
||||
* @param domainOfSite
|
||||
*
|
||||
* @return {@code true} if there is no site with the provided domain,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected boolean isUnique(final String domainOfSite) {
|
||||
|
||||
return !siteRepository.findByDomain(domainOfSite).isPresent();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void delete(final long siteId) {
|
||||
final Site site = siteRepository
|
||||
.findById(siteId)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No site with ID %d in the database.",
|
||||
siteId)));
|
||||
siteRepository.delete(site);
|
||||
sitesTableDataProvider.refreshAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.shared.ui.ContentMode;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.libreccm.ui.ConfirmDialog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class SitesTab extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = 9188476373782633282L;
|
||||
|
||||
private static final String COL_DOMAIN_OF_SITE = "domain_of_site";
|
||||
private static final String COL_IS_DEFAULT_SITE = "is_default_site";
|
||||
private static final String COL_DEFAULT_THEME = "default_theme";
|
||||
private static final String COL_APPLICATIONS = "applications";
|
||||
private static final String COL_EDIT = "edit";
|
||||
private static final String COL_DELETE = "delete";
|
||||
|
||||
protected SitesTab(final AdminViewController adminViewController) {
|
||||
|
||||
super();
|
||||
|
||||
final LocalizedTextsUtil adminTextsUtil = adminViewController
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final SitesController controller = adminViewController
|
||||
.getSitesController();
|
||||
|
||||
final Grid<SitesTableRowData> sitesGrid = new Grid<>();
|
||||
sitesGrid
|
||||
.addColumn(SitesTableRowData::getDomainOfSite)
|
||||
.setCaption(adminTextsUtil.getText(
|
||||
"ui.admin.sites.table.columns.domain.header"))
|
||||
.setId(COL_DOMAIN_OF_SITE);
|
||||
sitesGrid
|
||||
.addColumn(SitesTableRowData::isDefaultSite)
|
||||
.setCaption(adminTextsUtil.getText(
|
||||
"ui.admin.sites.table.columns.default_site.header"))
|
||||
.setId(COL_IS_DEFAULT_SITE);
|
||||
sitesGrid
|
||||
.addColumn(SitesTableRowData::getDefaultTheme)
|
||||
.setCaption(adminTextsUtil.getText(
|
||||
"ui.admin.sites.table.columns.default_theme.header"))
|
||||
.setId(COL_DEFAULT_THEME);
|
||||
sitesGrid
|
||||
.addComponentColumn(row -> {
|
||||
return new Label(String.join("\n",
|
||||
row.getApplications()),
|
||||
ContentMode.PREFORMATTED);
|
||||
})
|
||||
.setCaption(adminTextsUtil
|
||||
.getText("ui.admin.sites.table.columns.applications.header"))
|
||||
.setId(COL_APPLICATIONS);
|
||||
sitesGrid
|
||||
.addComponentColumn(row -> {
|
||||
final Button editButton = new Button(adminTextsUtil
|
||||
.getText("ui.admin.sites.table.buttons.edit"),
|
||||
VaadinIcons.EDIT);
|
||||
editButton.addClickListener(event -> {
|
||||
final Site site = adminViewController
|
||||
.getSitesController()
|
||||
.getSiteRepository()
|
||||
.findById(row.getSiteId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Site with ID %d in the database.",
|
||||
row.getSiteId())));
|
||||
final SiteEditor editor = new SiteEditor(
|
||||
site, adminViewController);
|
||||
editor.center();
|
||||
editor.setModal(true);
|
||||
editor.setWidth("66%");
|
||||
editor.setHeight("80%");
|
||||
UI.getCurrent().addWindow(editor);
|
||||
});
|
||||
editButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
|
||||
return editButton;
|
||||
})
|
||||
.setId(COL_EDIT);
|
||||
sitesGrid
|
||||
.addComponentColumn(row -> {
|
||||
if (row.isDeletable()) {
|
||||
final Button deleteButton = new Button(
|
||||
adminTextsUtil
|
||||
.getText("ui.admin.sites.table.buttons.delete"),
|
||||
VaadinIcons.MINUS_CIRCLE_O);
|
||||
deleteButton.addClickListener(event -> {
|
||||
|
||||
final ConfirmDialog dialog = new ConfirmDialog(() -> {
|
||||
adminViewController
|
||||
.getSitesController()
|
||||
.delete(row.getSiteId());
|
||||
|
||||
Notification.show(adminTextsUtil
|
||||
.getText("ui.admin.sites.site_deleted",
|
||||
new Object[]{row.getDomainOfSite()}),
|
||||
Notification.Type.TRAY_NOTIFICATION);
|
||||
return null;
|
||||
});
|
||||
dialog.setMessage(adminTextsUtil
|
||||
.getText("ui.admin.sites.site_delete.confirm",
|
||||
new Object[]{row.getDomainOfSite()}));
|
||||
dialog.setModal(true);
|
||||
dialog.center();
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
});
|
||||
deleteButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
|
||||
return deleteButton;
|
||||
} else {
|
||||
return new Label("");
|
||||
}
|
||||
})
|
||||
.setId(COL_DELETE);
|
||||
final HeaderRow headerRow = sitesGrid.prependHeaderRow();
|
||||
final HeaderCell headerCell = headerRow.join(COL_DOMAIN_OF_SITE,
|
||||
COL_IS_DEFAULT_SITE,
|
||||
COL_DEFAULT_THEME,
|
||||
COL_APPLICATIONS,
|
||||
COL_EDIT,
|
||||
COL_DELETE);
|
||||
final Button newSiteButton = new Button(adminTextsUtil
|
||||
.getText("ui.admin.sites.add_new_site_link"),
|
||||
VaadinIcons.PLUS_CIRCLE_O);
|
||||
newSiteButton.addStyleName(ValoTheme.BUTTON_TINY);
|
||||
newSiteButton.addClickListener(event -> {
|
||||
final SiteEditor editor = new SiteEditor(adminViewController);
|
||||
editor.center();
|
||||
editor.setWidth("66%");
|
||||
editor.setHeight("80%");
|
||||
UI.getCurrent().addWindow(editor);
|
||||
});
|
||||
final HorizontalLayout headerLayout
|
||||
= new HorizontalLayout(newSiteButton);
|
||||
headerCell.setComponent(headerLayout);
|
||||
sitesGrid.setDataProvider(adminViewController
|
||||
.getSitesController()
|
||||
.getSitesTableDataProvider());
|
||||
sitesGrid.setWidth("100%");
|
||||
|
||||
super.setCompositionRoot(sitesGrid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.sites.Site;
|
||||
import org.libreccm.sites.SiteRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
public class SitesTableDataProvider
|
||||
// extends AbstractBackEndDataProvider<SitesTableRowData, String> {
|
||||
extends AbstractDataProvider<SitesTableRowData, String> {
|
||||
|
||||
private static final long serialVersionUID = 2696603483924152498L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Inject
|
||||
private SiteRepository siteRepository;
|
||||
|
||||
// @Override
|
||||
// @Transactional(Transactional.TxType.REQUIRED)
|
||||
// public Stream<SitesTableRowData> fetchFromBackEnd(
|
||||
// final Query<SitesTableRowData, String> query) {
|
||||
//
|
||||
// final CriteriaBuilder criteriaBuilder = entityManager
|
||||
// .getCriteriaBuilder();
|
||||
// final CriteriaQuery<Site> criteriaQuery = criteriaBuilder
|
||||
// .createQuery(Site.class);
|
||||
// final Root<Site> from = criteriaQuery.from(Site.class);
|
||||
//
|
||||
// criteriaQuery.orderBy(criteriaBuilder.asc(from.get("domainOfSite")));
|
||||
//
|
||||
// return entityManager
|
||||
// .createQuery(criteriaQuery)
|
||||
// .setFirstResult(query.getOffset())
|
||||
// .setMaxResults(query.getLimit())
|
||||
// .getResultList()
|
||||
// .stream()
|
||||
// .map(this::buildRow);
|
||||
// }
|
||||
//
|
||||
// @Transactional(Transactional.TxType.REQUIRED)
|
||||
// @Override
|
||||
// public int sizeInBackEnd(final Query<SitesTableRowData, String> query) {
|
||||
//
|
||||
// return siteRepository.findAll().size();
|
||||
// }
|
||||
private SitesTableRowData buildRow(final Site site) {
|
||||
|
||||
final SitesTableRowData row = new SitesTableRowData();
|
||||
|
||||
row.setSiteId(site.getObjectId());
|
||||
row.setDomainOfSite(site.getDomainOfSite());
|
||||
row.setDefaultSite(site.isDefaultSite());
|
||||
row.setDefaultTheme(site.getDefaultTheme());
|
||||
row.setDeletable(site.getApplications().isEmpty());
|
||||
|
||||
final List<String> applications = site
|
||||
.getApplications()
|
||||
.stream()
|
||||
.map(application -> application.getPrimaryUrl())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
row.setApplications(applications);
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<SitesTableRowData, String> query) {
|
||||
return siteRepository.findAll().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Stream<SitesTableRowData> fetch(
|
||||
final Query<SitesTableRowData, String> query) {
|
||||
|
||||
final CriteriaBuilder criteriaBuilder = entityManager
|
||||
.getCriteriaBuilder();
|
||||
final CriteriaQuery<Site> criteriaQuery = criteriaBuilder
|
||||
.createQuery(Site.class);
|
||||
final Root<Site> from = criteriaQuery.from(Site.class);
|
||||
|
||||
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("domainOfSite")));
|
||||
|
||||
final List<Site> sites = entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setFirstResult(query.getOffset())
|
||||
.setMaxResults(query.getLimit())
|
||||
.getResultList();
|
||||
final List<SitesTableRowData> rows = new ArrayList<>();
|
||||
for (final Site site : sites) {
|
||||
final SitesTableRowData row = buildRow(site);
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
return rows.stream();
|
||||
|
||||
// return entityManager
|
||||
// .createQuery(criteriaQuery)
|
||||
// .setFirstResult(query.getOffset())
|
||||
// .setMaxResults(query.getLimit())
|
||||
// .getResultList()
|
||||
// .stream()
|
||||
// .map(this::buildRow);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class SitesTableRowData implements Comparable<SitesTableRowData>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4023882563583816258L;
|
||||
|
||||
private long siteId;
|
||||
|
||||
private String domainOfSite;
|
||||
|
||||
private boolean defaultSite;
|
||||
|
||||
private String defaultTheme;
|
||||
|
||||
private boolean deletable;
|
||||
|
||||
private List<String> applications;
|
||||
|
||||
protected SitesTableRowData() {
|
||||
applications = new ArrayList<>();
|
||||
}
|
||||
|
||||
public long getSiteId() {
|
||||
return siteId;
|
||||
}
|
||||
|
||||
public void setSiteId(final long siteId) {
|
||||
this.siteId = siteId;
|
||||
}
|
||||
|
||||
public String getDomainOfSite() {
|
||||
return domainOfSite;
|
||||
}
|
||||
|
||||
public void setDomainOfSite(final String domainOfSite) {
|
||||
this.domainOfSite = domainOfSite;
|
||||
}
|
||||
|
||||
public boolean isDefaultSite() {
|
||||
return defaultSite;
|
||||
}
|
||||
|
||||
public void setDefaultSite(final boolean defaultSite) {
|
||||
this.defaultSite = defaultSite;
|
||||
}
|
||||
|
||||
public String getDefaultTheme() {
|
||||
return defaultTheme;
|
||||
}
|
||||
|
||||
public void setDefaultTheme(final String defaultTheme) {
|
||||
this.defaultTheme = defaultTheme;
|
||||
}
|
||||
|
||||
public boolean isDeletable() {
|
||||
return deletable;
|
||||
}
|
||||
|
||||
public void setDeletable(final boolean deletable) {
|
||||
this.deletable = deletable;
|
||||
}
|
||||
|
||||
public List<String> getApplications() {
|
||||
return Collections.unmodifiableList(applications);
|
||||
}
|
||||
|
||||
protected void setApplications(final List<String> applications) {
|
||||
this.applications = new ArrayList<>(applications);
|
||||
}
|
||||
|
||||
protected void addApplication(final String application) {
|
||||
applications.add(application);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final SitesTableRowData other) {
|
||||
return domainOfSite.compareTo(other.getDomainOfSite());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
import com.arsdigita.util.SystemInformation;
|
||||
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class SystemInformationTab extends CustomComponent {
|
||||
|
||||
private static final long serialVersionUID = 2060924579790730222L;
|
||||
|
||||
private static final String COL_PROPERTY_NAME = "col_name";
|
||||
private static final String COL_PROPERTY_VALUE = "col_value";
|
||||
|
||||
protected SystemInformationTab(final AdminViewController controller) {
|
||||
|
||||
super();
|
||||
|
||||
final LocalizedTextsUtil adminTextsUtil = controller
|
||||
.getGlobalizationHelper()
|
||||
.getLocalizedTextsUtil(AdminUiConstants.ADMIN_BUNDLE);
|
||||
|
||||
final Grid<Map.Entry<String, String>> ccmSysInfoGrid = new Grid<>();
|
||||
ccmSysInfoGrid
|
||||
.setCaption(adminTextsUtil.getText("ui.admin.sysinfo.appinfo"));
|
||||
ccmSysInfoGrid
|
||||
.addColumn(Map.Entry::getKey)
|
||||
.setCaption("Property")
|
||||
.setId(COL_PROPERTY_NAME);
|
||||
ccmSysInfoGrid
|
||||
.addColumn(Map.Entry::getValue)
|
||||
.setCaption("Value")
|
||||
.setId(COL_PROPERTY_VALUE);
|
||||
ccmSysInfoGrid.setDataProvider(new CcmSysInfoDataProvider());
|
||||
ccmSysInfoGrid.setWidth("30em");
|
||||
|
||||
final Grid<Map.Entry<Object, Object>> systemPropsGrid = new Grid<>();
|
||||
systemPropsGrid.setCaption(adminTextsUtil
|
||||
.getText("ui.admin.sysinfo.java_system_properties"));
|
||||
systemPropsGrid
|
||||
.addColumn(entry -> Objects.toString(entry.getKey()))
|
||||
.setCaption("Name")
|
||||
.setId(COL_PROPERTY_NAME);
|
||||
systemPropsGrid
|
||||
.addColumn(entry -> Objects.toString(entry.getValue()))
|
||||
.setCaption("Vaue")
|
||||
.setId(COL_PROPERTY_VALUE);
|
||||
systemPropsGrid.setDataProvider(new JavaSystemPropertiesDataProvider());
|
||||
systemPropsGrid.setWidth("30em");
|
||||
|
||||
final Grid<Map.Entry<String, String>> xmlConfigGrid = new Grid<>();
|
||||
xmlConfigGrid
|
||||
.setCaption(adminTextsUtil.getText("ui.admin.sysinfo.xml_config"));
|
||||
xmlConfigGrid
|
||||
.addColumn(Map.Entry::getKey)
|
||||
.setCaption("Property")
|
||||
.setId(COL_PROPERTY_NAME);
|
||||
xmlConfigGrid
|
||||
.addColumn(Map.Entry::getValue)
|
||||
.setCaption("Value")
|
||||
.setId(COL_PROPERTY_VALUE);
|
||||
xmlConfigGrid.setDataProvider(new XmlConfigDataProvider());
|
||||
xmlConfigGrid.setWidth("30em");
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(ccmSysInfoGrid,
|
||||
systemPropsGrid,
|
||||
xmlConfigGrid);
|
||||
|
||||
super.setCompositionRoot(layout);
|
||||
}
|
||||
|
||||
private class CcmSysInfoDataProvider
|
||||
extends AbstractDataProvider<Map.Entry<String, String>, String> {
|
||||
|
||||
private static final long serialVersionUID = 958711041782982594L;
|
||||
|
||||
private final SystemInformation sysInfo = SystemInformation
|
||||
.getInstance();
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<Map.Entry<String, String>, String> query) {
|
||||
return sysInfo.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Map.Entry<String, String>> fetch(
|
||||
final Query<Map.Entry<String, String>, String> query) {
|
||||
|
||||
return sysInfo.getEntriesAsStream();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class JavaSystemPropertiesDataProvider
|
||||
extends AbstractDataProvider<Map.Entry<Object, Object>, String> {
|
||||
|
||||
private static final long serialVersionUID = -6971113377859500433L;
|
||||
|
||||
private final Properties systemProperties = System.getProperties();
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<Map.Entry<Object, Object>, String> query) {
|
||||
|
||||
return systemProperties.entrySet().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Map.Entry<Object, Object>> fetch(
|
||||
final Query<Map.Entry<Object, Object>, String> query) {
|
||||
|
||||
return systemProperties.entrySet().stream();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class XmlConfigDataProvider
|
||||
extends AbstractDataProvider<Map.Entry<String, String>, String> {
|
||||
|
||||
private static final long serialVersionUID = 3724329522046019159L;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<Map.Entry<String, String>, String> query) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Map.Entry<String, String>> fetch(
|
||||
final Query<Map.Entry<String, String>, String> query) {
|
||||
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
properties.put("XML Transformer Factory",
|
||||
getTransformerFactory());
|
||||
properties.put("XML Transformer", getTransformer());
|
||||
properties.put("XML Document Builder Factory",
|
||||
getDocumentBuilderFactory());
|
||||
properties.put("XML Document Builder", getDocumentBuilder());
|
||||
properties.put("SAX Parser Factory", getSaxParserFactory());
|
||||
properties.put("SAX Parser", getSaxParser());
|
||||
|
||||
return properties.entrySet().stream();
|
||||
}
|
||||
|
||||
private String getTransformerFactory() {
|
||||
return TransformerFactory
|
||||
.newInstance()
|
||||
.getClass()
|
||||
.getName();
|
||||
}
|
||||
|
||||
private String getTransformer() {
|
||||
try {
|
||||
return TransformerFactory
|
||||
.newInstance()
|
||||
.newTransformer()
|
||||
.getClass()
|
||||
.getName();
|
||||
} catch (TransformerConfigurationException ex) {
|
||||
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
private String getDocumentBuilderFactory() {
|
||||
return DocumentBuilderFactory
|
||||
.newInstance()
|
||||
.getClass()
|
||||
.getName();
|
||||
}
|
||||
|
||||
private String getDocumentBuilder() {
|
||||
try {
|
||||
return DocumentBuilderFactory
|
||||
.newInstance()
|
||||
.newDocumentBuilder()
|
||||
.getClass()
|
||||
.getName();
|
||||
} catch (ParserConfigurationException ex) {
|
||||
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
private String getSaxParserFactory() {
|
||||
return SAXParserFactory
|
||||
.newInstance()
|
||||
.getClass()
|
||||
.getName();
|
||||
}
|
||||
|
||||
private String getSaxParser() {
|
||||
try {
|
||||
return SAXParserFactory
|
||||
.newInstance()
|
||||
.newSAXParser()
|
||||
.getClass()
|
||||
.getName();
|
||||
} catch (ParserConfigurationException
|
||||
| SAXException ex) {
|
||||
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
import com.vaadin.ui.components.grid.HeaderCell;
|
||||
import com.vaadin.ui.components.grid.HeaderRow;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class UserDetails extends Window {
|
||||
|
||||
private static final long serialVersionUID = 7852981019990845392L;
|
||||
|
||||
private static final String COL_GROUP_NAME = "group_name";
|
||||
private static final String COL_GROUP_REMOVE = "group_remove";
|
||||
|
||||
private static final String COL_ROLE_NAME = "role_name";
|
||||
private static final String COL_ROLE_REMOVE = "role_remove";
|
||||
|
||||
private final User user;
|
||||
private final UsersController controller;
|
||||
|
||||
protected UserDetails(final User user, final UsersController controller) {
|
||||
|
||||
super(String.format("Details of user %s", user.getName()));
|
||||
|
||||
this.user = user;
|
||||
this.controller = controller;
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final Label userName = new Label(user.getName());
|
||||
userName.setCaption(bundle
|
||||
.getString("ui.admin.user_edit.username.label"));
|
||||
|
||||
final Label familyName = new Label(user.getFamilyName());
|
||||
familyName.setCaption(bundle
|
||||
.getString("ui.admin.user_edit.familyname.label"));
|
||||
|
||||
final Label givenName = new Label(user.getGivenName());
|
||||
givenName.setCaption(bundle
|
||||
.getString("ui.admin.user_edit.givenname.label"));
|
||||
|
||||
final Label emailAddress = new Label(user.getPrimaryEmailAddress()
|
||||
.getAddress());
|
||||
emailAddress.setCaption(bundle
|
||||
.getString("ui.admin.user_edit.emailAddress.label"));
|
||||
|
||||
final Label passwordResetRequired = new Label();
|
||||
if (user.isPasswordResetRequired()) {
|
||||
passwordResetRequired.setValue("Yes");
|
||||
} else {
|
||||
passwordResetRequired.setValue("No");
|
||||
}
|
||||
passwordResetRequired.setCaption(bundle
|
||||
.getString("ui.admin.user_edit.password_reset_required.label"));
|
||||
|
||||
final Label banned = new Label();
|
||||
if (user.isBanned()) {
|
||||
banned.setValue("Yes");
|
||||
} else {
|
||||
banned.setValue("No");
|
||||
}
|
||||
banned.setCaption(bundle.getString("ui.admin.user_edit.banned.label"));
|
||||
|
||||
final FormLayout formLayout = new FormLayout(userName,
|
||||
familyName,
|
||||
givenName,
|
||||
emailAddress,
|
||||
passwordResetRequired,
|
||||
banned);
|
||||
|
||||
final Button editButton = new Button(
|
||||
bundle.getString("ui.admin.users.table.edit"),
|
||||
event -> {
|
||||
final UserEditor editor = new UserEditor(user,
|
||||
controller);
|
||||
editor.setModal(true);
|
||||
editor.center();
|
||||
UI.getCurrent().addWindow(editor);
|
||||
});
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout,
|
||||
editButton);
|
||||
|
||||
final UserGroupsController groupsController = controller
|
||||
.getGroupsController();
|
||||
final Grid<Group> groupsGrid = new Grid<>();
|
||||
groupsGrid
|
||||
.addColumn(Group::getName)
|
||||
.setId(COL_GROUP_NAME)
|
||||
.setCaption("Group");
|
||||
groupsGrid
|
||||
.addComponentColumn(group -> {
|
||||
final Button removeButton = new Button(
|
||||
bundle.getString("ui.user.groups.remove"),
|
||||
VaadinIcons.MINUS_CIRCLE_O);
|
||||
removeButton.addClickListener(event -> {
|
||||
groupsController.removeUserFromGroup(user, group);
|
||||
groupsGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
removeButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return removeButton;
|
||||
})
|
||||
.setId(COL_GROUP_REMOVE);
|
||||
|
||||
groupsGrid.setWidth("100%");
|
||||
|
||||
final GroupRepository groupRepo = controller.getGroupRepository();
|
||||
|
||||
final HeaderRow groupsGridHeader = groupsGrid.prependHeaderRow();
|
||||
final Button addGroupButton = new Button("Add group");
|
||||
addGroupButton.setIcon(VaadinIcons.PLUS);
|
||||
addGroupButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
addGroupButton.addClickListener(event -> {
|
||||
final GroupSelector groupSelector = new GroupSelector(
|
||||
"Select group(s) to which the user is added.",
|
||||
"Add user to selected groups",
|
||||
controller.getGroupSelectorDataProvider(),
|
||||
groupRepo.findByMember(user),
|
||||
selectedGroups -> {
|
||||
selectedGroups.forEach(group -> {
|
||||
groupsController.addUserToGroup(user, group);
|
||||
});
|
||||
groupsGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
groupSelector.center();
|
||||
groupSelector.setWidth("80%");
|
||||
groupSelector.addCloseListener(closeEvent -> {
|
||||
groupsGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
UI.getCurrent().addWindow(groupSelector);
|
||||
});
|
||||
final HeaderCell groupsGridHeaderCell = groupsGridHeader
|
||||
.join(COL_GROUP_NAME, COL_GROUP_REMOVE);
|
||||
groupsGridHeaderCell
|
||||
.setComponent(new HorizontalLayout(addGroupButton));
|
||||
|
||||
final UserGroupsTableDataProvider groupsDataProvider = controller
|
||||
.getGroupsTableDataProvider();
|
||||
groupsDataProvider.setUser(user);
|
||||
groupsGrid.setDataProvider(groupsDataProvider);
|
||||
|
||||
final UserRolesController rolesController = controller
|
||||
.getRolesController();
|
||||
final Grid<Role> rolesGrid = new Grid<>();
|
||||
rolesGrid
|
||||
.addColumn(Role::getName)
|
||||
.setId(COL_ROLE_NAME)
|
||||
.setCaption("Role");
|
||||
rolesGrid
|
||||
.addComponentColumn(role -> {
|
||||
final Button removeButton = new Button(
|
||||
bundle.getString("ui.user.roles.remove"),
|
||||
VaadinIcons.MINUS_CIRCLE_O);
|
||||
removeButton.addClickListener(event -> {
|
||||
rolesController.removeRoleFromUser(role, user);
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
removeButton.addStyleNames(ValoTheme.BUTTON_TINY,
|
||||
ValoTheme.BUTTON_DANGER);
|
||||
return removeButton;
|
||||
})
|
||||
.setId(COL_ROLE_NAME);
|
||||
|
||||
rolesGrid.setWidth("100%");
|
||||
|
||||
final RoleRepository roleRepo = controller.getRoleRepository();
|
||||
|
||||
final HeaderRow rolesGridHeader = rolesGrid.prependHeaderRow();
|
||||
final Button addRoleButton = new Button("Add role");
|
||||
addRoleButton.setIcon(VaadinIcons.PLUS);
|
||||
addRoleButton.setStyleName(ValoTheme.BUTTON_TINY);
|
||||
addRoleButton.addClickListener(event -> {
|
||||
final RoleSelector roleSelector = new RoleSelector(
|
||||
"Select role(s) to add to group",
|
||||
"Add selected role(s) to group",
|
||||
controller.getRoleSelectorDataProvider(),
|
||||
roleRepo.findByParty(user),
|
||||
(selectedRoles -> {
|
||||
selectedRoles.forEach(role -> {
|
||||
rolesController.assignRoleToUser(role, user);
|
||||
});
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
}));
|
||||
roleSelector.addCloseListener(closeEvent -> {
|
||||
rolesGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
roleSelector.center();
|
||||
roleSelector.setWidth("80%");
|
||||
UI.getCurrent().addWindow(roleSelector);
|
||||
});
|
||||
final HeaderCell rolesGridHeaderCell = rolesGridHeader
|
||||
.join(COL_ROLE_NAME,
|
||||
COL_ROLE_REMOVE);
|
||||
rolesGridHeaderCell
|
||||
.setComponent(new HorizontalLayout(addRoleButton));
|
||||
|
||||
final UserRolesTableDataProvider rolesDataProvider = controller
|
||||
.getRolesTableDataProvider();
|
||||
rolesDataProvider.setUser(user);
|
||||
rolesGrid.setDataProvider(rolesDataProvider);
|
||||
|
||||
final TabSheet tabs = new TabSheet();
|
||||
tabs.addTab(layout, "Details");
|
||||
tabs.addTab(groupsGrid, "Groups");
|
||||
tabs.addTab(rolesGrid, "Roles");
|
||||
|
||||
setContent(tabs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,459 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.arsdigita.ui.admin.AdminUiConstants;
|
||||
|
||||
import com.vaadin.data.HasValue;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.FormLayout;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.PasswordField;
|
||||
import com.vaadin.ui.RadioButtonGroup;
|
||||
import com.vaadin.ui.TextField;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.core.EmailAddress;
|
||||
import org.libreccm.core.UnexpectedErrorException;
|
||||
import org.libreccm.security.ChallengeManager;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.security.UserManager;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
class UserEditor extends Window {
|
||||
|
||||
private static final long serialVersionUID = 7024424532574023431L;
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(UserEditor.class);
|
||||
|
||||
private enum PasswordOptions {
|
||||
|
||||
DO_NOTHING,
|
||||
GENERATE_AND_SEND,
|
||||
SET,
|
||||
}
|
||||
|
||||
private final User user;
|
||||
private final UserRepository userRepo;
|
||||
private final UserManager userManager;
|
||||
private final ChallengeManager challengeManager;
|
||||
|
||||
private boolean dataHasChanged = false;
|
||||
|
||||
private TextField userName;
|
||||
private TextField familyName;
|
||||
private TextField givenName;
|
||||
private TextField emailAddress;
|
||||
private RadioButtonGroup<PasswordOptions> passwordOptions;
|
||||
private PasswordField password;
|
||||
private PasswordField passwordConfirmation;
|
||||
private CheckBox passwordResetRequired;
|
||||
private CheckBox banned;
|
||||
|
||||
protected UserEditor(final UsersController controller) {
|
||||
|
||||
super("Create new user");
|
||||
|
||||
user = null;
|
||||
userRepo = controller.getUserRepository();
|
||||
userManager = controller.getUserManager();
|
||||
challengeManager = controller.getChallengeManager();
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
public UserEditor(final User user,
|
||||
final UsersController controller) {
|
||||
|
||||
super(String.format("Edit user %s", user.getName()));
|
||||
|
||||
this.user = user;
|
||||
userRepo = controller.getUserRepository();
|
||||
userManager = controller.getUserManager();
|
||||
challengeManager = controller.getChallengeManager();
|
||||
|
||||
addWidgets();
|
||||
}
|
||||
|
||||
private void addWidgets() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
final DataHasChangedListener dataHasChangedListener
|
||||
= new DataHasChangedListener();
|
||||
|
||||
userName = new TextField(bundle
|
||||
.getString("ui.admin.user_edit.username.label"));
|
||||
userName.setRequiredIndicatorVisible(true);
|
||||
userName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
familyName = new TextField(bundle
|
||||
.getString("ui.admin.user_edit.familyname.label"));
|
||||
familyName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
givenName = new TextField(bundle
|
||||
.getString("ui.admin.user_edit.givenname.label"));
|
||||
givenName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
emailAddress = new TextField(bundle
|
||||
.getString("ui.admin.user_edit.emailAddress.label"));
|
||||
emailAddress.setRequiredIndicatorVisible(true);
|
||||
givenName.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
passwordOptions = new RadioButtonGroup<PasswordOptions>(
|
||||
bundle.getString("ui.admin.user_edit.password_options.label"),
|
||||
new AbstractDataProvider<PasswordOptions, String>() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size(final Query<PasswordOptions, String> query) {
|
||||
if (user == null) {
|
||||
return PasswordOptions.values().length - 1;
|
||||
} else {
|
||||
return PasswordOptions.values().length;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<PasswordOptions> fetch(
|
||||
final Query<PasswordOptions, String> query) {
|
||||
if (user == null) {
|
||||
return Arrays
|
||||
.stream(PasswordOptions.values())
|
||||
.filter(option -> option != PasswordOptions.DO_NOTHING);
|
||||
} else {
|
||||
return Arrays.stream(PasswordOptions.values());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
passwordOptions.setItemCaptionGenerator(
|
||||
(final PasswordOptions item) -> {
|
||||
switch (item) {
|
||||
case GENERATE_AND_SEND:
|
||||
return bundle.getString(
|
||||
"ui.admin.user_edit.password_options.generate_and_send");
|
||||
case SET:
|
||||
return bundle.getString(
|
||||
"ui.admin.user_edit.password_options.set");
|
||||
case DO_NOTHING:
|
||||
return bundle.getString(
|
||||
"ui.admin.user_edit.password_options.do_nothing");
|
||||
default:
|
||||
throw new UnexpectedErrorException(String.format(
|
||||
"Unexpected value '%s' for password options.",
|
||||
item.toString()));
|
||||
}
|
||||
});
|
||||
|
||||
password = new PasswordField(bundle
|
||||
.getString("ui.admin.user_edit.password.label"));
|
||||
password.setRequiredIndicatorVisible(true);
|
||||
password.addValueChangeListener(dataHasChangedListener);
|
||||
|
||||
passwordConfirmation = new PasswordField(bundle
|
||||
.getString("ui.admin.user_set_password_confirm.label"));
|
||||
passwordConfirmation.setRequiredIndicatorVisible(true);
|
||||
|
||||
passwordOptions.addValueChangeListener(event -> {
|
||||
switch (event.getValue()) {
|
||||
case GENERATE_AND_SEND:
|
||||
password.setEnabled(false);
|
||||
password.setVisible(false);
|
||||
passwordConfirmation.setEnabled(false);
|
||||
passwordConfirmation.setVisible(false);
|
||||
break;
|
||||
case SET:
|
||||
password.setEnabled(true);
|
||||
password.setVisible(true);
|
||||
passwordConfirmation.setEnabled(true);
|
||||
passwordConfirmation.setVisible(true);
|
||||
break;
|
||||
case DO_NOTHING:
|
||||
password.setEnabled(false);
|
||||
password.setVisible(false);
|
||||
passwordConfirmation.setEnabled(false);
|
||||
passwordConfirmation.setVisible(false);
|
||||
break;
|
||||
default:
|
||||
throw new UnexpectedErrorException(String.format(
|
||||
"Unexpected value '%s' for password options.",
|
||||
event.getValue().toString()));
|
||||
}
|
||||
});
|
||||
|
||||
passwordOptions.setValue(PasswordOptions.GENERATE_AND_SEND);
|
||||
|
||||
final CheckBoxHasChangedListener checkBoxHasChangedListener
|
||||
= new CheckBoxHasChangedListener();
|
||||
|
||||
passwordResetRequired = new CheckBox(bundle
|
||||
.getString("ui.admin.user_edit.password_reset_required.label"));
|
||||
passwordResetRequired.addValueChangeListener(checkBoxHasChangedListener);
|
||||
|
||||
banned = new CheckBox(bundle
|
||||
.getString("ui.admin.user_edit.banned.label"));
|
||||
banned.addValueChangeListener(checkBoxHasChangedListener);
|
||||
|
||||
if (user == null) {
|
||||
banned.setVisible(false);
|
||||
banned.setEnabled(false);
|
||||
}
|
||||
|
||||
final Button submit = new Button();
|
||||
if (user == null) {
|
||||
submit.setCaption(bundle
|
||||
.getString("ui.admin.user.createpanel.header"));
|
||||
} else {
|
||||
submit.setCaption(bundle.getString("ui.admin.save"));
|
||||
}
|
||||
submit.addClickListener(event -> saveUser());
|
||||
|
||||
final Button cancel = new Button(bundle.getString("ui.admin.cancel"));
|
||||
cancel.addClickListener(event -> close());
|
||||
|
||||
final HorizontalLayout buttons = new HorizontalLayout(submit, cancel);
|
||||
|
||||
final FormLayout formLayout = new FormLayout(userName,
|
||||
familyName,
|
||||
givenName,
|
||||
emailAddress,
|
||||
passwordOptions,
|
||||
password,
|
||||
passwordConfirmation,
|
||||
passwordResetRequired,
|
||||
banned);
|
||||
|
||||
final VerticalLayout layout = new VerticalLayout(formLayout, buttons);
|
||||
|
||||
final Panel panel = new Panel(layout);
|
||||
if (user == null) {
|
||||
panel.setCaption(bundle
|
||||
.getString("ui.admin.user.createpanel.header"));
|
||||
} else {
|
||||
panel.setCaption(bundle
|
||||
.getString("ui.admin.user_details.edit"));
|
||||
}
|
||||
|
||||
setContent(panel);
|
||||
|
||||
if (user != null) {
|
||||
userName.setValue(user.getName());
|
||||
givenName.setValue(user.getGivenName());
|
||||
familyName.setValue(user.getFamilyName());
|
||||
emailAddress.setValue(user.getPrimaryEmailAddress().getAddress());
|
||||
passwordResetRequired.setValue(user.isPasswordResetRequired());
|
||||
banned.setValue(user.isBanned());
|
||||
passwordOptions.setValue(PasswordOptions.DO_NOTHING);
|
||||
}
|
||||
|
||||
dataHasChanged = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
if (dataHasChanged) {
|
||||
final ConfirmDiscardDialog dialog = new ConfirmDiscardDialog(
|
||||
this, "Are you sure to discard the changes made this user?");
|
||||
dialog.setModal(true);
|
||||
UI.getCurrent().addWindow(dialog);
|
||||
} else {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveUser() {
|
||||
|
||||
final ResourceBundle bundle = ResourceBundle
|
||||
.getBundle(AdminUiConstants.ADMIN_BUNDLE,
|
||||
UI.getCurrent().getLocale());
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
if (userName.getValue() == null
|
||||
|| userName.getValue().trim().isEmpty()) {
|
||||
userName.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.user_edit.username.error.not_empty")));
|
||||
valid = false;
|
||||
}
|
||||
if (emailAddress.getValue() == null
|
||||
|| emailAddress.getValue().trim().isEmpty()) {
|
||||
emailAddress.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.user.email_form.address.not_empty")));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if ((user == null || !user.getName().equals(userName.getValue()))
|
||||
&& userRepo.isNameInUse(userName.getValue())) {
|
||||
|
||||
userName.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.new_user_form.error"
|
||||
+ ".username_already_in_use")));
|
||||
valid = false;
|
||||
} else {
|
||||
userName.setComponentError(null);
|
||||
}
|
||||
|
||||
if ((user == null
|
||||
|| !user.getPrimaryEmailAddress().getAddress().equals(
|
||||
emailAddress.getValue()))
|
||||
&& userRepo.isEmailAddressInUse(emailAddress.getValue())) {
|
||||
|
||||
emailAddress.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.new_user_form.error.email_already_in_use")));
|
||||
valid = false;
|
||||
} else {
|
||||
if (!Pattern.matches(
|
||||
"^[^@<>\"\\t ]+@[^@<>\".\\t]+([.][^@<>\".\\n ]+)+$",
|
||||
emailAddress.getValue().trim())) {
|
||||
emailAddress.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.user_form.email_malformed")));
|
||||
valid = false;
|
||||
} else {
|
||||
emailAddress.setComponentError(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (passwordOptions.getValue() == PasswordOptions.SET) {
|
||||
if (password.getValue() == null
|
||||
|| password.getValue().trim().isEmpty()) {
|
||||
password.setComponentError(new UserError(bundle
|
||||
.getString(
|
||||
"ui.admin.set_password.new_password.error.not_empty")));
|
||||
}
|
||||
|
||||
if (!password.getValue().equals(passwordConfirmation.getValue())) {
|
||||
passwordConfirmation.setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.user_set_password.error.do_not_match")));
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User currentUser;
|
||||
if (user == null) {
|
||||
|
||||
final User newUser = userManager.createUser(givenName.getValue(),
|
||||
familyName.getValue(),
|
||||
userName.getValue(),
|
||||
emailAddress.getValue(),
|
||||
passwordConfirmation
|
||||
.getValue());
|
||||
|
||||
newUser.setPasswordResetRequired(passwordResetRequired.getValue());
|
||||
newUser.setBanned(banned.getValue());
|
||||
currentUser = newUser;
|
||||
|
||||
userRepo.save(newUser);
|
||||
} else {
|
||||
user.setName(userName.getValue().trim());
|
||||
user.setGivenName(givenName.getValue().trim());
|
||||
user.setFamilyName(familyName.getValue().trim());
|
||||
final EmailAddress email = user.getPrimaryEmailAddress();
|
||||
if (!email.getAddress().equals(emailAddress.getValue())) {
|
||||
email.setAddress(emailAddress.getValue());
|
||||
}
|
||||
user.setPasswordResetRequired(passwordResetRequired.getValue());
|
||||
user.setBanned(banned.getValue());
|
||||
|
||||
userRepo.save(user);
|
||||
currentUser = user;
|
||||
}
|
||||
|
||||
switch (passwordOptions.getValue()) {
|
||||
case GENERATE_AND_SEND: {
|
||||
userManager.updatePassword(currentUser, null);
|
||||
try {
|
||||
challengeManager.sendPasswordRecover(currentUser);
|
||||
} catch (MessagingException ex) {
|
||||
setComponentError(new UserError(bundle
|
||||
.getString("ui.admin.user_form"
|
||||
+ ".failed_to_send_password_challenge")));
|
||||
LOGGER.error(
|
||||
"Failed to send password challenge.",
|
||||
ex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SET:
|
||||
userManager.updatePassword(currentUser,
|
||||
passwordConfirmation.getValue());
|
||||
break;
|
||||
}
|
||||
|
||||
dataHasChanged = false;
|
||||
close();
|
||||
}
|
||||
|
||||
private class DataHasChangedListener
|
||||
implements HasValue.ValueChangeListener<String> {
|
||||
|
||||
private static final long serialVersionUID = -4698658552890778877L;
|
||||
|
||||
@Override
|
||||
public void valueChange(final HasValue.ValueChangeEvent<String> event) {
|
||||
dataHasChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class CheckBoxHasChangedListener implements
|
||||
HasValue.ValueChangeListener<Boolean> {
|
||||
|
||||
private static final long serialVersionUID = 1986372149566327203L;
|
||||
|
||||
@Override
|
||||
public void valueChange(final HasValue.ValueChangeEvent<Boolean> event) {
|
||||
dataHasChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.l10n.GlobalizationHelper;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupManager;
|
||||
import org.libreccm.security.GroupRepository;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class UserGroupsController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3226620773017042743L;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private GroupRepository groupRepo;
|
||||
|
||||
@Inject
|
||||
private GroupManager groupManager;
|
||||
|
||||
@Inject
|
||||
private UserRepository userRepo;
|
||||
|
||||
protected GlobalizationHelper getGlobalizationHelper() {
|
||||
return globalizationHelper;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void addUserToGroups(final User user, final Set<Group> groups) {
|
||||
|
||||
groups.forEach(group -> addUserToGroup(user, group));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void addUserToGroup(final User user, final Group group) {
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Group with ID %d in the database.",
|
||||
group.getPartyId())));
|
||||
|
||||
final User theUser = userRepo
|
||||
.findById(user.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No user with ID %d in the database. ",
|
||||
user.getPartyId())));
|
||||
|
||||
groupManager.addMemberToGroup(theUser, theGroup);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void removeUserFromGroup(final User user, final Group group) {
|
||||
|
||||
final Group theGroup = groupRepo
|
||||
.findById(group.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Group with ID %d in the database.",
|
||||
group.getPartyId())));
|
||||
|
||||
final User theUser = userRepo
|
||||
.findById(user.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No user with ID %d in the database. ",
|
||||
user.getPartyId())));
|
||||
|
||||
groupManager.removeMemberFromGroup(theUser, theGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import com.vaadin.cdi.ViewScoped;
|
||||
import com.vaadin.data.provider.AbstractDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.GroupMembership;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ViewScoped
|
||||
class UserGroupsTableDataProvider extends AbstractDataProvider<Group, String> {
|
||||
|
||||
private static final long serialVersionUID = 3321330114174366998L;
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
private User user;
|
||||
|
||||
@Override
|
||||
public boolean isInMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public int size(final Query<Group, String> query) {
|
||||
|
||||
Objects.requireNonNull(user,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setUser(User) before calling "
|
||||
+ "the count method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Long> criteriaQuery = builder
|
||||
.createQuery(Long.class);
|
||||
|
||||
final Root<GroupMembership> from = criteriaQuery
|
||||
.from(GroupMembership.class);
|
||||
|
||||
criteriaQuery
|
||||
.select(builder.count(from))
|
||||
.where(builder.equal(from.get("member"), user));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getSingleResult()
|
||||
.intValue();
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@Override
|
||||
public Stream<Group> fetch(final Query<Group, String> query) {
|
||||
|
||||
Objects.requireNonNull(user,
|
||||
"This data provider needs to be initalized "
|
||||
+ "by calling setUser(User) before calling "
|
||||
+ "the fetch method.");
|
||||
|
||||
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
|
||||
final CriteriaQuery<GroupMembership> criteriaQuery = builder
|
||||
.createQuery(GroupMembership.class);
|
||||
final Root<GroupMembership> from = criteriaQuery
|
||||
.from(GroupMembership.class);
|
||||
final Join<?, ?> join = from.join("group");
|
||||
criteriaQuery
|
||||
.where(builder.equal(from.get("member"), user))
|
||||
.orderBy(builder.asc(join.get("name")));
|
||||
|
||||
return entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.setMaxResults(query.getLimit())
|
||||
.setFirstResult(query.getOffset())
|
||||
.getResultList()
|
||||
.stream()
|
||||
.map(GroupMembership::getGroup);
|
||||
}
|
||||
|
||||
public void setUser(final User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* 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.admin.ui;
|
||||
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleManager;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.security.UserRepository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
class UserRolesController implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1136907020235869523L;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepo;
|
||||
|
||||
@Inject
|
||||
private RoleManager roleManager;
|
||||
|
||||
@Inject
|
||||
private UserRepository userRepo;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignRolesToUser(final Set<Role> roles, final User user) {
|
||||
|
||||
roles.forEach(role -> assignRoleToUser(role, user));
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void assignRoleToUser(final Role role, final User user) {
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
final User theUser = userRepo
|
||||
.findById(user.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No user with ID %d in the database. ",
|
||||
user.getPartyId())));
|
||||
|
||||
roleManager.assignRoleToParty(theRole, theUser);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
protected void removeRoleFromUser(final Role role, final User user) {
|
||||
|
||||
final Role theRole = roleRepo
|
||||
.findById(role.getRoleId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No Role with ID %d in the database.",
|
||||
role.getRoleId())));
|
||||
|
||||
final User theUser = userRepo
|
||||
.findById(user.getPartyId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String
|
||||
.format("No group with id %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
user.getPartyId())));
|
||||
|
||||
roleManager.removeRoleFromParty(theRole, theUser);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue