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>
|
<type>jar</type>
|
||||||
<includes>
|
<includes>
|
||||||
<include>assets/</include>
|
<include>assets/</include>
|
||||||
<include>VAADIN/</include>
|
|
||||||
</includes>
|
</includes>
|
||||||
</overlay>
|
</overlay>
|
||||||
<overlay>
|
<overlay>
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,6 @@
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<includes>
|
<includes>
|
||||||
<include>assets/</include>
|
<include>assets/</include>
|
||||||
<include>VAADIN/</include>
|
|
||||||
</includes>
|
</includes>
|
||||||
</overlay>
|
</overlay>
|
||||||
<overlay>
|
<overlay>
|
||||||
|
|
|
||||||
|
|
@ -67,12 +67,6 @@
|
||||||
<artifactId>log4j-api</artifactId>
|
<artifactId>log4j-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Vaadin dependencies for Vaadin prototype -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-cdi</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<reporting>
|
<reporting>
|
||||||
|
|
|
||||||
|
|
@ -98,21 +98,7 @@
|
||||||
<groupId>org.apache.shiro</groupId>
|
<groupId>org.apache.shiro</groupId>
|
||||||
<artifactId>shiro-web</artifactId>
|
<artifactId>shiro-web</artifactId>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
@ -259,23 +245,6 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</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>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
@ -349,7 +318,7 @@
|
||||||
<linkXref>true</linkXref>
|
<linkXref>true</linkXref>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<targetJdk>1.8</targetJdk>
|
<targetJdk>1.8</targetJdk>
|
||||||
<!-- <rulesets>
|
<!-- <rulesets>
|
||||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
<ruleset>/rulesets/java/braces.xml</ruleset>
|
<ruleset>/rulesets/java/braces.xml</ruleset>
|
||||||
<ruleset>/rulesets/java/clone.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>
|
<artifactId>Saxon-HE</artifactId>
|
||||||
</dependency>
|
</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 -->
|
<!-- Export Import Libraries -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
@ -377,37 +358,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</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>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
@ -481,7 +431,7 @@
|
||||||
<linkXref>true</linkXref>
|
<linkXref>true</linkXref>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<targetJdk>1.8</targetJdk>
|
<targetJdk>1.8</targetJdk>
|
||||||
<!-- <rulesets>
|
<!-- <rulesets>
|
||||||
<ruleset>/rulesets/java/basic.xml</ruleset>
|
<ruleset>/rulesets/java/basic.xml</ruleset>
|
||||||
<ruleset>/rulesets/java/braces.xml</ruleset>
|
<ruleset>/rulesets/java/braces.xml</ruleset>
|
||||||
<ruleset>/rulesets/java/clone.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