diff --git a/ccm-cms/pom.xml b/ccm-cms/pom.xml
index db6022225..b7a8401f6 100644
--- a/ccm-cms/pom.xml
+++ b/ccm-cms/pom.xml
@@ -90,6 +90,20 @@
shiro-web
+
+
+ com.vaadin
+ vaadin-themes
+
+
+ com.vaadin
+ vaadin-client-compiled
+
+
+ com.vaadin
+ vaadin-cdi
+
+
junit
junit
@@ -255,6 +269,24 @@
+
+
+ com.vaadin
+ vaadin-maven-plugin
+
+
+
+ clean
+ resources
+ update-theme
+ update-widgetset
+ compile-theme
+ compile
+
+
+
+
+
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsUI.java b/ccm-cms/src/main/java/org/librecms/ui/CmsUI.java
new file mode 100644
index 000000000..4a5523cc8
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsUI.java
@@ -0,0 +1,70 @@
+/*
+ * 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 Jens Pelzetter
+ */
+@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);
+ }
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsView.java b/ccm-cms/src/main/java/org/librecms/ui/CmsView.java
new file mode 100644
index 000000000..1dd49b246
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsView.java
@@ -0,0 +1,59 @@
+/*
+ * 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 Jens Pelzetter
+ */
+@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 Label("Placeholder"), "Search");
+ tabSheet.addTab(new Label("Placeholder"), "My tasks");
+
+ super.setCompositionRoot(tabSheet);
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java b/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java
new file mode 100644
index 000000000..6c89ce0cf
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/CmsViewController.java
@@ -0,0 +1,63 @@
+/*
+ * 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 javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@ViewScoped
+class CmsViewController {
+
+ @Inject
+ private GlobalizationHelper globalizationHelper;
+
+ @Inject
+ private PermissionManager permissionManager;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ @Inject
+ private ContentSectionsGridDataProvider sectionsDataProvider;
+
+ protected GlobalizationHelper getGlobalizationHelper() {
+ return globalizationHelper;
+ }
+
+ protected PermissionManager getPermissionManager() {
+ return permissionManager;
+ }
+
+ protected PermissionChecker getPermissionChecker() {
+ return permissionChecker;
+ }
+
+ protected ContentSectionsGridDataProvider getSectionsDataProvider() {
+ return sectionsDataProvider;
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionView.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionView.java
new file mode 100644
index 000000000..fe7952393
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionView.java
@@ -0,0 +1,99 @@
+/*
+ * 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.Label;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.themes.ValoTheme;
+import org.librecms.contentsection.ContentSection;
+import org.librecms.contentsection.ContentSectionRepository;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@CDIView(value = ContentSectionView.VIEWNAME,
+ uis = {CmsUI.class})
+class ContentSectionView implements View {
+
+ private static final long serialVersionUID = 602851260519364741L;
+
+ public static final String VIEWNAME = "ContentSection";
+
+ private final ContentSectionViewController controller;
+
+ private ContentSection selectedSection;
+
+ private final TabSheet tabSheet;
+ private final Panel noSectionPanel;
+
+ @Inject
+ ContentSectionView(final ContentSectionViewController controller) {
+
+ super();
+
+ this.controller = controller;
+
+ tabSheet = new TabSheet();
+
+ noSectionPanel = new Panel();
+ noSectionPanel.setVisible(false);
+ }
+
+ @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
+ .getSectionRepo();
+
+ final Optional contentSection = sectionRepo
+ .findByLabel(parameters);
+
+ if (contentSection.isPresent()) {
+ selectedSection = contentSection.get();
+ } 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);
+ }
+ }
+
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionViewController.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionViewController.java
new file mode 100644
index 000000000..6603e656a
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionViewController.java
@@ -0,0 +1,56 @@
+/*
+ * 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.librecms.contentsection.ContentSectionRepository;
+
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@ViewScoped
+class ContentSectionViewController {
+
+ @Inject
+ private GlobalizationHelper globalizationHelper;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ @Inject
+ private ContentSectionRepository sectionRepo;
+
+ public GlobalizationHelper getGlobalizationHelper() {
+ return globalizationHelper;
+ }
+
+ public PermissionChecker getPermissionChecker() {
+ return permissionChecker;
+ }
+
+ public ContentSectionRepository getSectionRepo() {
+ return sectionRepo;
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGrid.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGrid.java
new file mode 100644
index 000000000..034502c02
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGrid.java
@@ -0,0 +1,165 @@
+/*
+ * 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.navigator.Navigator;
+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 Jens Pelzetter
+ */
+class ContentSectionsGrid extends Grid {
+
+ 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;
+
+ final PermissionChecker permissionChecker = controller
+ .getPermissionChecker();
+
+ 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");
+
+ 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 adminPrivileges = controller
+ .getPermissionManager()
+ .listDefiniedPrivileges(AdminPrivileges.class);
+ final List 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("");
+ }
+
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGridDataProvider.java b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGridDataProvider.java
new file mode 100644
index 000000000..3ff144b23
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/ContentSectionsGridDataProvider.java
@@ -0,0 +1,86 @@
+/*
+ * 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 Jens Pelzetter
+ */
+@ViewScoped
+class ContentSectionsGridDataProvider
+ extends AbstractBackEndDataProvider {
+
+ private static final long serialVersionUID = 2173898409635046482L;
+
+ @Inject
+ private EntityManager entityManager;
+
+ @Inject
+ private ContentSectionRepository sectionRepo;
+
+ @Override
+ protected Stream fetchFromBackEnd(
+ final Query query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(ContentSection.class);
+ final Root from = criteriaQuery
+ .from(ContentSection.class);
+
+ return entityManager
+ .createQuery(criteriaQuery)
+ .setMaxResults(query.getLimit())
+ .setFirstResult(query.getOffset())
+ .getResultList()
+ .stream();
+ }
+
+ @Override
+ protected int sizeInBackEnd(final Query query) {
+
+ final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+ final CriteriaQuery criteriaQuery = builder
+ .createQuery(Long.class);
+ final Root from = criteriaQuery
+ .from(ContentSection.class);
+
+ criteriaQuery.select(builder.count(from));
+
+ return entityManager
+ .createQuery(criteriaQuery)
+ .getSingleResult()
+ .intValue();
+ }
+
+}
diff --git a/ccm-cms/src/main/java/org/librecms/ui/LoginView.java b/ccm-cms/src/main/java/org/librecms/ui/LoginView.java
new file mode 100644
index 000000000..749af72d7
--- /dev/null
+++ b/ccm-cms/src/main/java/org/librecms/ui/LoginView.java
@@ -0,0 +1,41 @@
+/*
+ * 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 Jens Pelzetter
+ */
+@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;
+ }
+
+}
diff --git a/ccm-cms/src/main/resources/META-INF/beans.xml b/ccm-cms/src/main/resources/META-INF/beans.xml
new file mode 100644
index 000000000..445d8f3f5
--- /dev/null
+++ b/ccm-cms/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/ccm-core/src/main/java/org/libreccm/admin/ui/LoginView.java b/ccm-core/src/main/java/org/libreccm/admin/ui/LoginView.java
index df36daeb2..001eede83 100644
--- a/ccm-core/src/main/java/org/libreccm/admin/ui/LoginView.java
+++ b/ccm-core/src/main/java/org/libreccm/admin/ui/LoginView.java
@@ -18,180 +18,165 @@
*/
package org.libreccm.admin.ui;
-import com.arsdigita.kernel.KernelConfig;
import com.vaadin.cdi.CDIView;
-import com.vaadin.event.ShortcutAction;
-import com.vaadin.navigator.View;
-import com.vaadin.navigator.ViewChangeListener;
-import com.vaadin.server.UserError;
-import com.vaadin.ui.Alignment;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.CustomComponent;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.Notification;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.PasswordField;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.VerticalLayout;
-import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authc.UsernamePasswordToken;
-import org.apache.shiro.subject.Subject;
-import org.libreccm.configuration.ConfigurationManager;
-import org.libreccm.l10n.GlobalizationHelper;
+import org.libreccm.ui.AbstractLoginView;
-import java.util.ResourceBundle;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
/**
*
* @author Jens Pelzetter
*/
-@CDIView(LoginView.VIEWNAME)
-public class LoginView extends CustomComponent implements View {
+@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 = "login";
+ public static final String VIEWNAME = "adminlogin";
- @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 -> {
+ @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);
// }
// });
-// userName.addBlurListener(event -> {
+//
+// password.addValueChangeListener(event -> {
// if (userName.getValue() != null
// && !userName.getValue().trim().isEmpty()
// && password.getValue() != null
// && !password.getValue().trim().isEmpty()) {
-// submitButton.removeClickShortcut();
+// submitButton.setEnabled(true);
+// submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
// }
// });
- 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"));
- }
-
+//
+//// 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"));
+// }
}
diff --git a/ccm-core/src/main/java/org/libreccm/ui/AbstractLoginView.java b/ccm-core/src/main/java/org/libreccm/ui/AbstractLoginView.java
new file mode 100644
index 000000000..3a729d542
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/ui/AbstractLoginView.java
@@ -0,0 +1,200 @@
+/*
+ * 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.ui;
+
+import com.arsdigita.kernel.KernelConfig;
+
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.server.UserError;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.PasswordField;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.libreccm.admin.ui.AdminView;
+import org.libreccm.admin.ui.Header;
+import org.libreccm.configuration.ConfigurationManager;
+import org.libreccm.l10n.GlobalizationHelper;
+
+import java.util.ResourceBundle;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public abstract class AbstractLoginView extends CustomComponent implements View{
+
+ private static final long serialVersionUID = 1481112180843568446L;
+
+ @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 AbstractLoginView() {
+
+ 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());
+ }
+
+ protected abstract String getTargetView();
+
+ 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(getTargetView());
+ }
+
+ @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"));
+ }
+
+
+
+
+}