From 8e05fe06af29306b33c3e6f9460b7b74a71f5c8b Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 17 Feb 2016 19:00:18 +0000 Subject: [PATCH] CCM NG: Administration UI basic structure git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3867 8810af33-2d31-482b-a856-94f89814c4df --- .../java/com/arsdigita/ui/SiteBanner.java | 53 ++ .../src/main/java/com/arsdigita/ui/UI.java | 101 ++-- .../main/java/com/arsdigita/ui/UIConfig.java | 68 ++- .../java/com/arsdigita/ui/UiInitializer.java | 37 ++ .../java/com/arsdigita/ui/UserBanner.java | 134 +++++ .../arsdigita/ui/admin/AdminConstants.java | 8 +- .../com/arsdigita/ui/admin/AdminServlet.java | 235 +++++---- .../arsdigita/ui/admin/AdminUiConstants.java | 499 ++++++++++++++++++ .../ui/admin/ApplicationsAdminTab.java | 38 ++ .../ui/admin/CategoriesAdminTab.java | 39 ++ .../arsdigita/ui/admin/RegistryAdminTab.java | 39 ++ .../ui/admin/UsersGroupsRolesTab.java | 37 ++ .../configuration/ConfigurationException.java | 67 +++ .../main/java/org/libreccm/core/CcmCore.java | 4 +- .../org/libreccm/security/CcmShiroRealm.java | 86 +-- .../com/arsdigita/ui/UIResources.properties | 31 ++ .../arsdigita/ui/UIResources_de.properties | 31 ++ .../arsdigita/ui/UIResources_en.properties | 31 ++ .../arsdigita/ui/UIResources_fr.properties | 27 + .../ui/admin/AdminResources.properties | 3 + .../ui/admin/AdminResources_de.properties | 3 + .../ui/admin/AdminResources_en.properties | 3 + .../ui/admin/AdminResources_fr.properties | 3 + .../docrepo/AbstractResourceRepository.java | 93 ++-- .../docrepo/RepositoryRepository.java | 24 +- .../libreccm/shortcuts/ui/ShortcutForm.java | 10 +- .../libreccm/shortcuts/ui/ShortcutsTable.java | 5 +- 27 files changed, 1453 insertions(+), 256 deletions(-) create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/SiteBanner.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/UiInitializer.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/UserBanner.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/AdminUiConstants.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/ApplicationsAdminTab.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/CategoriesAdminTab.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/RegistryAdminTab.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/UsersGroupsRolesTab.java create mode 100644 ccm-core/src/main/java/org/libreccm/configuration/ConfigurationException.java create mode 100755 ccm-core/src/main/resources/com/arsdigita/ui/UIResources.properties create mode 100644 ccm-core/src/main/resources/com/arsdigita/ui/UIResources_de.properties create mode 100755 ccm-core/src/main/resources/com/arsdigita/ui/UIResources_en.properties create mode 100755 ccm-core/src/main/resources/com/arsdigita/ui/UIResources_fr.properties diff --git a/ccm-core/src/main/java/com/arsdigita/ui/SiteBanner.java b/ccm-core/src/main/java/com/arsdigita/ui/SiteBanner.java new file mode 100644 index 000000000..ea8fc36e2 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/SiteBanner.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleComponent; +import com.arsdigita.kernel.security.SecurityConfig; +import com.arsdigita.web.Web; +import com.arsdigita.xml.Element; + +import static com.arsdigita.ui.UI.*; + +/** + * + * @author Jens Pelzetter + */ +public class SiteBanner extends SimpleComponent { + + @Override + public void generateXML(final PageState state, final Element parentElem) { + final Element contentElem = parentElem.newChildElement("ui:siteBanner", + UI_XML_NS); + + exportAttributes(contentElem); + + contentElem.addAttribute("hostname", getHostname()); + contentElem.addAttribute("sitename", getSiteName()); + } + + protected String getHostname() { + return Web.getConfig().getServer(); + } + + protected String getSiteName() { + return Web.getConfig().getSiteName(); + } +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/UI.java b/ccm-core/src/main/java/com/arsdigita/ui/UI.java index cb455ee56..bce3e84ec 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/UI.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/UI.java @@ -15,7 +15,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ - package com.arsdigita.ui; import com.arsdigita.ui.login.LoginConstants; @@ -26,32 +25,45 @@ import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; /** - *

A central location for commonly used UI services and their accessories.

+ *

+ * A central location for commonly used UI services and their accessories.

* * * @author pb */ public abstract class UI { - /** Private loggin instance. */ + /** + * Private loggin instance. + */ private static final Logger s_log = Logger.getLogger(UI.class); - /** The UI XML namespace. */ + /** + * The UI XML namespace. + */ public static final String UI_XML_NS = "http://www.arsdigita.com/ui/1.0"; + public static final String UI_BUNDLE_NAME = "com.arsdigita.ui.UIResources"; + private static final UIConfig s_config = UIConfig.getConfig(); - /** URL for systems public top level page (entry or start page). */ + /** + * URL for systems public top level page (entry or start page). + */ private static final String s_rootPageURL = s_config.getRootPageUrl(); - /** URL to page a user should be redirected to after login. */ - private static final String s_userRedirectURL = s_config.getUserRedirectUrl(); - /** (Absolute) URL for workspace page. */ + /** + * URL to page a user should be redirected to after login. + */ + private static final String s_userRedirectURL = s_config + .getUserRedirectUrl(); + /** + * (Absolute) URL for workspace page. + */ private static final String s_workspaceURL = s_config.getWorkspaceUrl(); - /** * Provides a handle to the UI config record. - * + * * @return Instance of LegacyUIConfig */ public static UIConfig getConfig() { @@ -60,16 +72,16 @@ public abstract class UI { /** * Provides an absolute URL (leading slash) into the system top-level page - * (entry page / start page). It is relative to document root without any + * (entry page / start page). It is relative to document root without any * constant prefix if there is one configured. - * + * * Method is typically called by servlets and especially by JSP's. - * + * * Currently just a wrapper script to getRootPageURL() because req is * currently ignored. * - * @param req HttpServletRequest, may be used to determin the context of - * the current thread (application), currently not used and + * @param req HttpServletRequest, may be used to determin the context of the + * current thread (application), currently not used and * introduced here for backwards compatibility * * @return URL for top-level page as String @@ -80,9 +92,9 @@ public abstract class UI { /** * Provides an absolute URL (leading slash) into the system top-level page - * (entry page / start page). It is relative to document root without any + * (entry page / start page). It is relative to document root without any * constant prefix if there is one configured. - * + * * Method is typically called by servlets and especially by JSP's. * * @return URL for top-level page as String @@ -95,14 +107,14 @@ public abstract class UI { * Provides the absolute URL of a page, which redirects an incomming request * based on some clients property, usually whether the user is logged in, * either to a general public page or to a user (client) specific page. - * + * * It is relative to document root including leading slash but without any * constant prefix if there is one configured. * * It is typically used after login to redirect to an appropriate page, by - * default to /peremissions/. A site should configure an application - * to their specific purposes. e.g ccm-cms provides a page - * content-center/redirect.jsp which redirects a user to the content-center + * default to /peremissions/. A site should configure an application to + * their specific purposes. e.g ccm-cms provides a page + * content-center/redirect.jsp which redirects a user to the content-center * if logged in. * * @return full URL of a user redirect page, may be null @@ -112,14 +124,17 @@ public abstract class UI { } /** - * Wrapper method for {@see getUserRedirectURL()} - * which redirects a user to the content-center if logged in. - * + * Wrapper method for { + * + * @see getUserRedirectURL()} which redirects a user to the content-center + * if logged in. + * * Method is specifically used by various redirect JSP's. * - * @param req HttpServletRequest, may be used to determin the context of - * the current thread (application), currently not used and + * @param req HttpServletRequest, may be used to determin the context of the + * current thread (application), currently not used and * introduced here for backwards compatibility + * * @return full URL of a user redirect page, may be null */ public static String getUserRedirectURL(HttpServletRequest req) { @@ -144,17 +159,17 @@ public abstract class UI { } /** - * Provides the absolute URL for the system workspace page. - * It is relative to document root including leading slash but without any - * constant prefix if there is one configured. - * + * Provides the absolute URL for the system workspace page. It is relative + * to document root including leading slash but without any constant prefix + * if there is one configured. + * * Method is typically called by servlets and especially by JSP's. - * + * * Currently just a wrapper script to getWorkspaceURL() because req is * currently ignored. * - * @param req HttpServletRequest, may be used to determin the context of - * the current thread (application), currently not used and + * @param req HttpServletRequest, may be used to determin the context of the + * current thread (application), currently not used and * introduced here for backwards compatibility * * @return URL for workspace page as String @@ -165,19 +180,17 @@ public abstract class UI { return getWorkspaceURL(); } - // //////////////////////////////////////////////////////////////////////// // Various deprfecated methods, to be removed as soon as invoking code is // refactored. // //////////////////////////////////////////////////////////////////////// - - /** - * Provides an absolute URL (leading slash) into the system login page. - * It is relative to document root without any constant prefix if there is - * one configured. + * Provides an absolute URL (leading slash) into the system login page. It + * is relative to document root without any constant prefix if there is one + * configured. * * @return URL for login page as String + * * @deprecated use Login.getLoginPageURL()() instead */ public static String getLoginPageURL() { @@ -190,6 +203,7 @@ public abstract class UI { * one configured. * * @return url String for new user registration page as String + * * @deprecated use LoginServlet.getCookiesExplainPageURL() instead */ public static String getCookiesExplainPageURL() { @@ -197,11 +211,12 @@ public abstract class UI { } /** - * Provides an absolute URL (leading slash) for a password recovery page. - * It is relative to document root without any constant prefix if there is - * one configured. + * Provides an absolute URL (leading slash) for a password recovery page. It + * is relative to document root without any constant prefix if there is one + * configured. * * @return url String for new user registration page as String + * * @deprecated use LoginServlet.getRecoverPasswordPageURL() instead */ public static String getRecoverPasswordPageURL() { @@ -214,6 +229,7 @@ public abstract class UI { * one configured. * * @return url String for new user registration page as String + * * @deprecated use LoginServlet.getEditUserProfilePageURL() instead */ public static String getEditUserProfilePageURL() { @@ -226,6 +242,7 @@ public abstract class UI { * configured. * * @return URL for logout page as String + * * @deprecated use LoginServlet.getLogoutPageURL() instead */ public static String getLogoutPageURL() { diff --git a/ccm-core/src/main/java/com/arsdigita/ui/UIConfig.java b/ccm-core/src/main/java/com/arsdigita/ui/UIConfig.java index 99cb9c86b..61e925bb6 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/UIConfig.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/UIConfig.java @@ -18,8 +18,11 @@ */ package com.arsdigita.ui; +import com.arsdigita.bebop.Component; + import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.Configuration; +import org.libreccm.configuration.ConfigurationException; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.configuration.Setting; @@ -37,66 +40,91 @@ import javax.enterprise.inject.spi.CDI; */ @Configuration public final class UIConfig { - + @Setting private List defaultLayout = Arrays.asList(new String[]{ "top:com.arsdigita.ui.UserBanner", "bottom:com.arsdigita.ui.SiteBanner", "bottom:com.arsdigita.ui.DebugPanel" }); - + @Setting private String rootPageUrl = "/register/"; - + @Setting private String userRedirectUrl = "/permissions/"; - + @Setting private String workspaceUrl = "/pvt/"; - + public static UIConfig getConfig() { final ConfigurationManager confManager = CdiUtil.createCdiUtil() .findBean(ConfigurationManager.class); - + return confManager.findConfiguration(UIConfig.class); } - + public UIConfig() { super(); } - + public List getDefaultLayout() { return new ArrayList<>(defaultLayout); } - + public void setDefaultLayout(final List defaultLayout) { this.defaultLayout = defaultLayout; } - + + public SimplePageLayout buildDefaultLayout() { + final SimplePageLayout layout = new SimplePageLayout(); + + defaultLayout.forEach(c -> { + final String[] tokens = c.split(":"); + if (tokens.length != 2) { + throw new ConfigurationException( + "Default layout not provided in the correct format."); + } + + Class clazz; + try { + clazz = Class.forName(tokens[1]); + } catch (ClassNotFoundException ex) { + throw new ConfigurationException(String.format( + "Component \"%s\" not found.", tokens[1]), + ex); + } + + layout.addComponent(clazz, tokens[0]); + }); + + return layout; + } + public String getRootPageUrl() { return rootPageUrl; } - + public void setRootPageUrl(final String rootPageUrl) { this.rootPageUrl = rootPageUrl; } - + public String getUserRedirectUrl() { return userRedirectUrl; } - + public void setUserRedirectUrl(final String userRedirectUrl) { this.userRedirectUrl = userRedirectUrl; } - + public String getWorkspaceUrl() { return workspaceUrl; } - + public void setWorkspaceUrl(final String workspaceUrl) { this.workspaceUrl = workspaceUrl; } - + @Override public int hashCode() { int hash = 7; @@ -106,7 +134,7 @@ public final class UIConfig { hash = 31 * hash + Objects.hashCode(workspaceUrl); return hash; } - + @Override public boolean equals(final Object obj) { if (this == obj) { @@ -130,14 +158,14 @@ public final class UIConfig { } return Objects.equals(defaultLayout, other.getDefaultLayout()); } - + @Override public String toString() { final StringJoiner joiner = new StringJoiner(", "); if (defaultLayout != null) { defaultLayout.forEach(s -> joiner.add(s)); } - + return String.format("%s{ " + "defaultLayout = \"%s\", " + "rootPageUrl = \"%s\", " @@ -150,5 +178,5 @@ public final class UIConfig { userRedirectUrl, workspaceUrl); } - + } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/UiInitializer.java b/ccm-core/src/main/java/com/arsdigita/ui/UiInitializer.java new file mode 100644 index 000000000..3890627b7 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/UiInitializer.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui; + +/** + * + * @author Jens Pelzetter + */ +public class UiInitializer { + + public UiInitializer() { + + } + + public void init() { + final UIConfig uiConfig = UIConfig.getConfig(); + + SimplePage.setDefaultLayout(uiConfig.buildDefaultLayout()); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/UserBanner.java b/ccm-core/src/main/java/com/arsdigita/ui/UserBanner.java new file mode 100644 index 000000000..666272571 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/UserBanner.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SimpleComponent; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; +import com.arsdigita.ui.login.LoginConstants; +import com.arsdigita.ui.login.LoginServlet; +import com.arsdigita.web.URL; +import com.arsdigita.xml.Element; + +import org.apache.shiro.subject.Subject; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.User; +import org.libreccm.security.UserRepository; + +import javax.servlet.http.HttpServletRequest; + +import static com.arsdigita.ui.UI.*; + +/** + * + * @author Jens Pelzetter + */ +public class UserBanner extends SimpleComponent { + + @Override + public void generateXML(final PageState state, + final Element parentElem) { + + super.generateXML(state, parentElem); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final Subject subject = cdiUtil.findBean(Subject.class); + + final Element contentElem = parentElem.newChildElement("ui:userBanner", + UI_XML_NS); + + exportAttributes(contentElem); + + if (subject.isAuthenticated()) { + final KernelConfig config = KernelConfig.getConfig(); + final UserRepository userRepository = cdiUtil.findBean( + UserRepository.class); + + final User user; + if ("email".equals(config.getPrimaryUserIdentifier())) { + user = userRepository.findByEmailAddress( + (String) subject.getPrincipal()); + } else { + user = userRepository + .findByName((String) subject.getPrincipal()); + } + + if (user != null) { + contentElem.addAttribute("givenName", user.getGivenName()); + contentElem.addAttribute("familyName", user.getFamilyName()); + contentElem.addAttribute("screenName", user.getName()); + contentElem.addAttribute("primaryEmail", + user.getPrimaryEmailAddress() + .toString()); + contentElem.addAttribute("userID", + Long.toString(user.getPartyId())); + } + } + + final HttpServletRequest request = state.getRequest(); + + contentElem.addAttribute("changePasswordLabel", + (String) new GlobalizedMessage( + "ui.admin.change_password", + UI_BUNDLE_NAME).localize(request)); + + contentElem.addAttribute("helpLabel", + (String) new GlobalizedMessage( + "ui.admin.help", + UI_BUNDLE_NAME).localize(request)); + + contentElem.addAttribute("portalLabel", + (String) new GlobalizedMessage( + "ui.admin.portal", + UI_BUNDLE_NAME).localize(request)); + + contentElem.addAttribute("signoutLabel", + (String) new GlobalizedMessage( + "ui.admin.signout", + UI_BUNDLE_NAME).localize(request)); + + contentElem.addAttribute("greeting", + (String) new GlobalizedMessage( + "ui.admin.greeting", + UI_BUNDLE_NAME).localize(request)); + + contentElem.addAttribute("workspaceURL", + URL.there(state.getRequest(), + UI.getWorkspaceURL()).toString()); + + contentElem.addAttribute("loginURL", + URL.there(state.getRequest(), + LoginConstants.LOGIN_PAGE_URL) + .toString()); + + contentElem.addAttribute("logoutURL", + URL.there(state.getRequest(), + LoginServlet.getLogoutPageURL()) + .toString()); + + contentElem.addAttribute("changePasswordURL", + URL.there(state.getRequest(), + LoginServlet + .getChangePasswordPageURL()) + .toString()); + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminConstants.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminConstants.java index f8aebea03..c16d2ed95 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminConstants.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminConstants.java @@ -23,11 +23,11 @@ import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.globalization.GlobalizedMessage; /** - * Centralize place for all constants used in the admin UI. - * + * Centralised place for all constants used in the administration UI. + * * @author David Dao - * @version $Revision$ $Date$ */ +@Deprecated interface AdminConstants { /** @@ -61,6 +61,8 @@ interface AdminConstants { Label USER_TAB_TITLE = new Label(new GlobalizedMessage("ui.admin.tab.user", BUNDLE_NAME)); + + Label GROUP_TAB_TITLE = new Label(new GlobalizedMessage("ui.admin.tab.group", BUNDLE_NAME)); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java index 0c91441c5..d0617ccab 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java @@ -24,8 +24,10 @@ import com.arsdigita.bebop.PageFactory; import com.arsdigita.bebop.TabbedPane; import com.arsdigita.dispatcher.AccessDeniedException; import com.arsdigita.dispatcher.DispatcherHelper; +import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.templating.Templating; -import com.arsdigita.util.Assert; +import com.arsdigita.ui.SiteBanner; +import com.arsdigita.ui.UserBanner; import com.arsdigita.web.BaseApplicationServlet; import com.arsdigita.web.LoginSignal; import com.arsdigita.xml.Document; @@ -37,8 +39,6 @@ import org.libreccm.security.PermissionChecker; import org.libreccm.web.CcmApplication; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; import javax.enterprise.inject.spi.CDI; @@ -50,7 +50,7 @@ import javax.servlet.http.HttpServletResponse; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.ConfigurationManager; -import static com.arsdigita.ui.admin.AdminConstants.*; +import static com.arsdigita.ui.admin.AdminUiConstants.*; /** * Web Developer Support Application Servlet class, central entry point to @@ -73,8 +73,9 @@ public class AdminServlet implements AdminConstants { private static final long serialVersionUID = -3912367600768871630L; - - private static final Logger LOGGER = LogManager.getLogger(AdminServlet.class); + + private static final Logger LOGGER = LogManager + .getLogger(AdminServlet.class); /** * Logger instance for debugging @@ -84,7 +85,8 @@ public class AdminServlet * URL (pathinfo) -> Page object mapping. Based on it (and the http request * url) the doService method to selects a page to display */ - private final Map pages = new HashMap(); +// private final Map pages = new HashMap(); + private Page adminPage; /** * User extension point, overwrite this method to setup a URL - page mapping @@ -96,6 +98,49 @@ public class AdminServlet //addPage("/", buildAdminIndexPage()); // index page at address ~/ds // addPage("/index.jsp", buildIndexPage()); // index page at address ~/ds + adminPage = PageFactory.buildPage("admin", "LibreCCM NG Admin"); + adminPage.addGlobalStateParam(USER_ID_PARAM); + adminPage.addGlobalStateParam(GROUP_ID_PARAM); + adminPage.addGlobalStateParam(APPLICATIONS_ID_PARAM); + + adminPage.add(new UserBanner()); + adminPage.add(new SiteBanner()); + + //Create tab bar + final TabbedPane tabbedPane = new TabbedPane(); + tabbedPane.setIdAttr("page-body"); + + tabbedPane.addTab( + new Label(new GlobalizedMessage("ui.admin.tab.applications", + BUNDLE_NAME)), + new ApplicationsAdminTab()); + + tabbedPane.addTab( + new Label(new GlobalizedMessage( + "ui.admin.tab.users_groups_roles.title", + BUNDLE_NAME)), + new UsersGroupsRolesTab()); + + tabbedPane.addTab( + new Label(new GlobalizedMessage("ui.admin.tab.categories.title", + BUNDLE_NAME)), + new CategoriesAdminTab()); + + tabbedPane.addTab( + new Label(new GlobalizedMessage("ui.admin.tab.registry.title", + BUNDLE_NAME)), + new RegistryAdminTab()); + + tabbedPane.addTab( + new Label(new GlobalizedMessage("ui.admin.tab.sysinfo.title", + BUNDLE_NAME)), + new SystemInformationTab()); + + //page.add(new Label("admin")); + adminPage.add(tabbedPane); + + adminPage.lock(); + } /** @@ -121,47 +166,48 @@ public class AdminServlet final PermissionChecker permissionChecker = cdiUtil.findBean( PermissionChecker.class); - final ConfigurationManager confManager = CDI.current().select(ConfigurationManager.class).get(); + final ConfigurationManager confManager = CDI.current().select( + ConfigurationManager.class).get(); if (confManager == null) { throw new IllegalStateException(); } - - LOGGER.debug("Checking if subject {} is authenticated...", + + LOGGER.debug("Checking if subject {} is authenticated...", subject.toString()); LOGGER.debug("Current session is: {}", sreq.getSession().getId()); - LOGGER.debug("Current Shiro session is {}", + LOGGER.debug("Current Shiro session is {}", subject.getSession().getId().toString()); if (!subject.isAuthenticated()) { - LOGGER.debug("Subject {} is not authenticated, redirecting to login...", - subject.toString()); + LOGGER.debug( + "Subject {} is not authenticated, redirecting to login...", + subject.toString()); throw new LoginSignal(sreq); } - /* Determine access privilege: Admin privileges must be granted */ - LOGGER.debug("Subject is loggedin, checking if subject has required permissions..."); + LOGGER.debug( + "Subject is loggedin, checking if subject has required permissions..."); if (!permissionChecker.isPermitted("admin")) { LOGGER.debug("Subject does *not* have required permissions. " - + "Access denied."); + + "Access denied."); throw new AccessDeniedException("User is not an administrator"); } - + LOGGER.debug("Serving admin page..."); - /* Want admin to always show the latest stuff... */ + /* Want admin to always show the latest stuff... */ DispatcherHelper.cacheDisable(sresp); // /////// Everything OK here - DO IT /////////////// - String pathInfo = sreq.getPathInfo(); - Assert.exists(pathInfo, "String pathInfo"); - if (pathInfo.length() > 1 && pathInfo.endsWith("/")) { - /* NOTE: ServletAPI specifies, pathInfo may be empty or will - * start with a '/' character. It currently carries a - * trailing '/' if a "virtual" page, i.e. not a real jsp, but - * result of a servlet mapping. But Application requires url - * NOT to end with a trailing '/' for legacy free applications. */ - pathInfo = pathInfo.substring(0, pathInfo.length() - 1); - } - +// String pathInfo = sreq.getPathInfo(); +// Assert.exists(pathInfo, "String pathInfo"); +// if (pathInfo.length() > 1 && pathInfo.endsWith("/")) { +// /* NOTE: ServletAPI specifies, pathInfo may be empty or will +// * start with a '/' character. It currently carries a +// * trailing '/' if a "virtual" page, i.e. not a real jsp, but +// * result of a servlet mapping. But Application requires url +// * NOT to end with a trailing '/' for legacy free applications. */ +// pathInfo = pathInfo.substring(0, pathInfo.length() - 1); +// } // final Page page = pages.get(pathInfo); // if (page == null) { // sresp.sendError(404, "No such page for path " + pathInfo); @@ -169,12 +215,7 @@ public class AdminServlet // final Document doc = page.buildDocument(sreq, sresp); // Templating.getPresentationManager().servePage(doc, sreq, sresp); // } - final Page page = PageFactory.buildPage("admin", "LibreCCM NG Admin"); - page.add(new Label("admin")); - - page.lock(); - - final Document doc = page.buildDocument(sreq, sresp); + final Document doc = adminPage.buildDocument(sreq, sresp); Templating.getPresentationManager().servePage(doc, sreq, sresp); } @@ -184,70 +225,68 @@ public class AdminServlet * @param pathInfo url stub for a page to display * @param page Page object to display */ - private void addPage(final String pathInfo, final Page page) { - Assert.exists(pathInfo, String.class); - Assert.exists(page, Page.class); - // Current Implementation requires pathInfo to start with a leading '/' - // SUN Servlet API specifies: "PathInfo *may be empty* or will start - // with a '/' character." - Assert.isTrue(pathInfo.charAt(0) == '/', "path starts not with '/'"); - - pages.put(pathInfo, page); - } - +// private void addPage(final String pathInfo, final Page page) { +// Assert.exists(pathInfo, String.class); +// Assert.exists(page, Page.class); +// // Current Implementation requires pathInfo to start with a leading '/' +// // SUN Servlet API specifies: "PathInfo *may be empty* or will start +// // with a '/' character." +// Assert.isTrue(pathInfo.charAt(0) == '/', "path starts not with '/'"); +// +// pages.put(pathInfo, page); +// } /** * Index page for the admin section */ - private Page buildAdminIndexPage() { - - final Page page = PageFactory.buildPage("admin", PAGE_TITLE_LABEL); - page.addGlobalStateParam(USER_ID_PARAM); - page.addGlobalStateParam(GROUP_ID_PARAM); - page.addGlobalStateParam(APPLICATIONS_ID_PARAM); - - /* - * Create User split panel. - * Note: Will change soon. - */ - //final AdminSplitPanel userSplitPanel = new AdminSplitPanel(USER_NAVBAR_TITLE); -// final UserBrowsePane browsePane = new UserBrowsePane(); -// userSplitPanel.addTab(USER_TAB_SUMMARY, new UserSummaryPane(userSplitPanel, browsePane)); -// userSplitPanel.addTab(USER_TAB_BROWSE, browsePane); -// userSplitPanel.addTab(USER_TAB_SEARCH, new UserSearchPane(userSplitPanel, browsePane)); -// userSplitPanel.addTab(USER_TAB_CREATE_USER, new CreateUserPane(userSplitPanel)); - // Create the Admin's page tab bar - final TabbedPane tabbedPane = new TabbedPane(); - tabbedPane.setIdAttr("page-body"); - - /** - * Create and add info tab - */ - //tabbedPane.addTab(INFO_TAB_TITLE, new AdminInfoTab()); - /* - * Create and add the user and group tabs. - */ - //tabbedPane.addTab(USER_TAB_TITLE, userSplitPanel); - final GroupAdministrationTab groupAdminTab - = new GroupAdministrationTab(); - tabbedPane.addTab(USER_TAB_TITLE, new UserAdministrationTab(tabbedPane, - groupAdminTab)); - tabbedPane.addTab(GROUP_TAB_TITLE, groupAdminTab); - - /* - * Create application administration panel - */ - tabbedPane.addTab(APPLICATIONS_TAB_TITLE, - new ApplicationsAdministrationTab()); - -// browsePane.setTabbedPane(tabbedPane); -// browsePane.setGroupAdministrationTab(groupAdminTab); - //Add System information tab - tabbedPane.addTab(SYSINFO_TAB_TITLE, new SystemInformationTab()); - - page.add(tabbedPane); - page.lock(); - - return page; - } - +// private Page buildAdminIndexPage() { +// +// final Page page = PageFactory.buildPage("admin", PAGE_TITLE_LABEL); +// page.addGlobalStateParam(USER_ID_PARAM); +// page.addGlobalStateParam(GROUP_ID_PARAM); +// page.addGlobalStateParam(APPLICATIONS_ID_PARAM); +// +// /* +// * Create User split panel. +// * Note: Will change soon. +// */ +// //final AdminSplitPanel userSplitPanel = new AdminSplitPanel(USER_NAVBAR_TITLE); +//// final UserBrowsePane browsePane = new UserBrowsePane(); +//// userSplitPanel.addTab(USER_TAB_SUMMARY, new UserSummaryPane(userSplitPanel, browsePane)); +//// userSplitPanel.addTab(USER_TAB_BROWSE, browsePane); +//// userSplitPanel.addTab(USER_TAB_SEARCH, new UserSearchPane(userSplitPanel, browsePane)); +//// userSplitPanel.addTab(USER_TAB_CREATE_USER, new CreateUserPane(userSplitPanel)); +// // Create the Admin's page tab bar +// final TabbedPane tabbedPane = new TabbedPane(); +// tabbedPane.setIdAttr("page-body"); +// +// /** +// * Create and add info tab +// */ +// //tabbedPane.addTab(INFO_TAB_TITLE, new AdminInfoTab()); +// /* +// * Create and add the user and group tabs. +// */ +// //tabbedPane.addTab(USER_TAB_TITLE, userSplitPanel); +// final GroupAdministrationTab groupAdminTab +// = new GroupAdministrationTab(); +// tabbedPane.addTab(USER_TAB_TITLE, new UserAdministrationTab(tabbedPane, +// groupAdminTab)); +// tabbedPane.addTab(GROUP_TAB_TITLE, groupAdminTab); +// +// /* +// * Create application administration panel +// */ +// tabbedPane.addTab(APPLICATIONS_TAB_TITLE, +// new ApplicationsAdministrationTab()); +// +//// browsePane.setTabbedPane(tabbedPane); +//// browsePane.setGroupAdministrationTab(groupAdminTab); +// //Add System information tab +// tabbedPane.addTab(SYSINFO_TAB_TITLE, new SystemInformationTab()); +// +// page.add(tabbedPane); +// page.lock(); +// +// return page; +// } } diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminUiConstants.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminUiConstants.java new file mode 100644 index 000000000..d1c457c46 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminUiConstants.java @@ -0,0 +1,499 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.globalization.GlobalizedMessage; + +/** + * + * @author Jens Pelzetter + */ +public final class AdminUiConstants { + + /** + * The XML namespace used by administration components. + */ + public static final String ADMIN_XML_NS + = "http://www.arsdigita.com/admin-ui/1.0"; + + /** + * Globalisation resource for administration UI. + */ + public static final String BUNDLE_NAME + = "com.arsdigita.ui.admin.AdminResources"; + + /** + * Navigational dimension bar labels. + */ + // Label MY_WORKSPACE_LABEL = new Label + // (new GlobalizedMessage("ui.admin.nav.workspace", + // BUNDLE_NAME)); + // Label LOG_OUT_LABEL = new Label + // (new GlobalizedMessage("ui.admin.nav.logout", + // BUNDLE_NAME)); + /** + * Administration page title + */ + public static final Label PAGE_TITLE_LABEL = new Label( + new GlobalizedMessage("ui.admin.dispatcher.title", + BUNDLE_NAME)); + + /** + * Administration main tab names. + */ + public static final Label USER_TAB_TITLE = new Label(new GlobalizedMessage( + "ui.admin.tab.user", + BUNDLE_NAME)); + + public static final Label GROUP_TAB_TITLE = new Label(new GlobalizedMessage( + "ui.admin.tab.group", + BUNDLE_NAME)); + + public static final Label APPLICATIONS_TAB_TITLE = new Label( + new GlobalizedMessage("ui.admin.tab.applications", + BUNDLE_NAME)); + + public static final Label SYSINFO_TAB_TITLE = new Label( + new GlobalizedMessage("ui.admin.tab.sysinfo.title", BUNDLE_NAME)); + + public static final GlobalizedMessage USER_NAVBAR_TITLE + = new GlobalizedMessage( + "ui.admin.tab.user.navbartitle", + BUNDLE_NAME); + + /** + * Tabbed pane indices + */ + public static final int USER_TAB_INDEX = 2; + public static final int GROUP_TAB_INDEX = 3; + + /** + * User tab name + */ + public static final Label USER_TAB_SUMMARY = new Label( + new GlobalizedMessage("ui.admin.tab.user.summary", + BUNDLE_NAME)); + public static final Label USER_TAB_BROWSE = new Label(new GlobalizedMessage( + "ui.admin.tab.user.browse", + BUNDLE_NAME)); + public static final Label USER_TAB_SEARCH = new Label(new GlobalizedMessage( + "ui.admin.tab.user.search", + BUNDLE_NAME)); + public static final Label USER_TAB_CREATE_USER = new Label( + new GlobalizedMessage("ui.admin.tab.user.createuser", + BUNDLE_NAME)); + + public static final int USER_TAB_SUMMARY_INDEX = 0; + public static final int USER_TAB_BROWSE_INDEX = 1; + public static final int USER_TAB_SEARCH_INDEX = 2; + public static final int USER_TAB_CREATE_USER_INDEX = 3; + + /** + * Global state parameters. + */ + public static final BigDecimalParameter GROUP_ID_PARAM + = new BigDecimalParameter("group_id"); + + public static final BigDecimalParameter APPLICATIONS_ID_PARAM + = new BigDecimalParameter( + "application_id"); + + public static final BigDecimalParameter USER_ID_PARAM + = new BigDecimalParameter("user_id"); + + /** + * User summary panel. + */ + public static final Label SUMMARY_PANEL_HEADER = new Label( + new GlobalizedMessage("ui.admin.user.summarypanel.header", BUNDLE_NAME)); + + public static final Label CREATE_USER_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.user.summarypanel.createUser", BUNDLE_NAME)); + + public static final Label TOTAL_USERS_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.user.summarypanel.totalusers", BUNDLE_NAME)); + + /** + * User browse panel. + */ + public static final Label BROWSE_USER_PANEL_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.user.browsepanel.header", + BUNDLE_NAME)); + + public static final Label USER_INFO_LABEL = new Label(new GlobalizedMessage( + "ui.admin.user.userinfo.header", + BUNDLE_NAME)); + + public static final Label USER_EDIT_PANEL_HEADER = new Label( + new GlobalizedMessage("ui.admin.user.useredit.header", + BUNDLE_NAME)); + + public static final Label USER_GROUP_PANEL_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.user.groupmembership.header", + BUNDLE_NAME)); + + public static final Label USER_DELETE_FAILED_PANEL_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.user.action.delete.failed.header", + BUNDLE_NAME)); + + public static final Label USER_PASSWORD_PANEL_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.user.password.header", + BUNDLE_NAME)); + + public static final Label USER_ACTION_PANEL_HEADER = new Label( + new GlobalizedMessage("ui.admin.user.action.header", + BUNDLE_NAME)); + + public static final Label USER_ACTION_CONTINUE = new Label( + new GlobalizedMessage("ui.admin.user.action.continue", + BUNDLE_NAME)); + + public static final Label USER_DELETE_LABEL = new Label( + new GlobalizedMessage("ui.admin.user.delete.label", + BUNDLE_NAME)); + + public static final Label USER_BAN_LABEL = new Label(new GlobalizedMessage( + "ui.admin.user.ban.label", + BUNDLE_NAME)); + + public static final Label USER_UNBAN_LABEL = new Label( + new GlobalizedMessage("ui.admin.user.unban.label", + BUNDLE_NAME)); + + public static final GlobalizedMessage USER_DELETE_CONFIRMATION + = new GlobalizedMessage( + "ui.admin.user.delete.confirm", BUNDLE_NAME); + + public static final GlobalizedMessage USER_BAN_CONFIRMATION + = new GlobalizedMessage( + "ui.admin.user.ban.confirm", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_UNBAN_CONFIRMATION + = new GlobalizedMessage( + "ui.admin.user.unban.confirm", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_DELETE_FAILED_MSG + = new GlobalizedMessage( + "ui.admin.user.delete.failed.label", BUNDLE_NAME); + + public static final Label USER_TAB_EXTREME_ACTION_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.user.browsepanel.extremeaction", + BUNDLE_NAME)); + + public static final Label UPDATE_USER_PASSWORD_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.user.browsepanel.updatePassword", + BUNDLE_NAME)); + + public static final Label BECOME_USER_LABEL = new Label( + new GlobalizedMessage("ui.admin.user.browsepanel.becomeUser", + BUNDLE_NAME)); + + /** + * Create new user panel. + */ + public static final Label CREATE_USER_PANEL_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.user.createpanel.header", + BUNDLE_NAME)); + + /** + * User search panel. + */ + public static final Label SEARCH_PANEL_HEADER = new Label( + new GlobalizedMessage("ui.admin.user.search.header", + BUNDLE_NAME)); + + public static final Label PASSWORD_FORM_LABEL_PASSWORD = new Label( + new GlobalizedMessage( + "ui.admin.user.userpasswordform.passwordlabel", + BUNDLE_NAME)); + + public static final Label PASSWORD_FORM_LABEL_CONFIRMATION_PASSWORD + = new Label(new GlobalizedMessage( + "ui.admin.user.userpasswordform.confirmpasswordlabel", + BUNDLE_NAME)); + + public static final Label PASSWORD_FORM_LABEL_QUESTION = new Label( + new GlobalizedMessage( + "ui.admin.user.userpasswordform.question", + BUNDLE_NAME), false); + + public static final Label PASSWORD_FORM_LABEL_ANSWER = new Label( + new GlobalizedMessage( + "ui.admin.user.userpasswordform.answer", + BUNDLE_NAME), false); + + public static final GlobalizedMessage PASSWORD_FORM_SUBMIT + = new GlobalizedMessage( + "ui.admin.user.userpasswordform.submit", + BUNDLE_NAME); + + /** + * Constants for user add/edit form. + */ + public static final String USER_FORM_ADD = "user-add-form"; + public static final String USER_FORM_EDIT = "user-edit-form"; + public static final String USER_FORM_INPUT_FIRST_NAME = "firstname"; + public static final String USER_FORM_INPUT_LAST_NAME = "lastname"; + public static final String USER_FORM_INPUT_PASSWORD = "password"; + public static final String USER_FORM_INPUT_PASSWORD_CONFIRMATION + = "password_confirmation"; + public static final String USER_FORM_INPUT_QUESTION = "question"; + public static final String USER_FORM_INPUT_ANSWER = "answer"; + public static final String USER_FORM_INPUT_PRIMARY_EMAIL = "email"; + public static final String USER_FORM_INPUT_ADDITIONAL_EMAIL + = "additional_email"; + public static final String USER_FORM_INPUT_SCREEN_NAME = "screenname"; + public static final String USER_FORM_INPUT_SSO = "sso_login"; + public static final String USER_FORM_INPUT_URL = "url"; + public static final String USER_FORM_INPUT_URL_DEFAULT = "http://"; + + public static final Label USER_FORM_LABEL_FIRST_NAME = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.firstname", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_LAST_NAME = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.lastname", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_PASSWORD = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.password", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_PASSWORD_CONFIRMATION = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.confirmation", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_QUESTION = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.question", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_ANSWER = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.answer", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_PRIMARY_EMAIL = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.primaryemail", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_ADDITIONAL_EMAIL = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.additionalemail", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_ADDITIONAL_EMAIL_LIST = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.additionalemaillist", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_SCREEN_NAME = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.screenname", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_SSO = new Label( + new GlobalizedMessage( + "ui.admin.user.addeditform.ssologinname", + BUNDLE_NAME)); + + public static final Label USER_FORM_LABEL_URL = new Label( + new GlobalizedMessage("ui.admin.user.addeditform.url", + BUNDLE_NAME)); + + public static final Label USER_FORM_DELETE_ADDITIONAL_EMAIL = new Label( + new GlobalizedMessage("ui.admin.user.addeditform.deleteemail", + BUNDLE_NAME)); + + public static final GlobalizedMessage USER_FORM_SUBMIT + = new GlobalizedMessage( + "ui.admin.user.addeditform.submit", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_FORM_ERROR_SCREEN_NAME_NOT_UNIQUE + = new GlobalizedMessage( + "ui.admin.user.addeditform.error.screenname.notunique", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_FORM_ERROR_PRIMARY_EMAIL_NOT_UNIQUE + = new GlobalizedMessage( + "ui.admin.user.addeditform.error.primaryemail.notunique", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_FORM_ERROR_PASSWORD_NOT_MATCH + = new GlobalizedMessage( + "ui.admin.user.addeditform.error.password.notmatch", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_FORM_ERROR_ANSWER_NULL + = new GlobalizedMessage( + "ui.admin.user.addeditform.error.answer.null", + BUNDLE_NAME); + + public static final GlobalizedMessage USER_FORM_ERROR_ANSWER_WHITESPACE + = new GlobalizedMessage( + "ui.admin.user.addeditform.error.answer.whitespace", + BUNDLE_NAME); + + /** + * Constants for group add/edit form. + */ + public static final String GROUP_FORM_ADD = "group-add-form"; + public static final String GROUP_FORM_EDIT = "group-edit-form"; + public static final String GROUP_FORM_INPUT_NAME = "name"; + public static final String GROUP_FORM_INPUT_PRIMARY_EMAIL = "email"; + + public static final Label GROUP_FORM_LABEL_NAME = new Label( + new GlobalizedMessage( + "ui.admin.groups.addeditform.namelabel", + BUNDLE_NAME)); + + public static final Label GROUP_FORM_LABEL_PRIMARY_EMAIL = new Label( + new GlobalizedMessage( + "ui.admin.groups.addeditform.primaryemaillabel", + BUNDLE_NAME)); + + public static final GlobalizedMessage GROUP_FORM_SUBMIT + = new GlobalizedMessage( + "ui.admin.groups.addeditform.submit", BUNDLE_NAME); + + /** + * Constants for group administration tab. + */ + public static final Label GROUP_ACTION_CONTINUE = new Label( + new GlobalizedMessage("ui.admin.groups.actioncontinue", + BUNDLE_NAME)); + + public static final GlobalizedMessage GROUP_DELETE_FAILED_MSG + = new GlobalizedMessage( + "ui.admin.groups.groupdeletefailed", + BUNDLE_NAME); + + public static final Label GROUP_INFORMATION_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.groups.groupinformation", + BUNDLE_NAME)); + + public static final Label SUBGROUP_HEADER = new Label(new GlobalizedMessage( + "ui.admin.groups.subgroups", + BUNDLE_NAME)); + + public static final Label GROUP_EDIT_HEADER = new Label( + new GlobalizedMessage("ui.admin.groups.groupedit", + BUNDLE_NAME)); + public static final Label ADD_SUBGROUP_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.add", + BUNDLE_NAME)); + + public static final Label SUBMEMBER_HEADER = new Label( + new GlobalizedMessage("ui.admin.groups.submembers", + BUNDLE_NAME)); + + public static final Label DELETE_GROUP_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.delete", + BUNDLE_NAME)); + + public static final Label GROUP_EXTREME_ACTIONS_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.groups.extremeaction", + BUNDLE_NAME)); + + public static final Label GROUP_DELETE_FAILED_HEADER = new Label( + new GlobalizedMessage( + "ui.admin.groups.deletefailed", + BUNDLE_NAME)); + + public static final Label ADD_GROUP_LABEL = new Label(new GlobalizedMessage( + "ui.admin.groups.addgrouplabel", + BUNDLE_NAME)); + public static final Label EDIT_GROUP_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.edit", + BUNDLE_NAME)); + + public static final Label SUBGROUP_COUNT_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.groups.subgroupcountlabel", + BUNDLE_NAME)); + public static final String GROUP_DELETE_CONFIRMATION + = "Are you sure you want to delete this group?"; + + public static final Label ADD_SUBMEMBER_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.addsubmemberlabel", + BUNDLE_NAME)); + + public static final Label REMOVE_SUBMEMBER_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.groups.removesubmemberlabel", + BUNDLE_NAME)); + public static final Label ADD_EXISTING_GROUP_TO_SUBGROUPS_LABEL = new Label( + new GlobalizedMessage( + "ui.admin.groups.addExisting", + BUNDLE_NAME)); + + public static final Label REMOVE_SUBGROUP_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.removeExisting", + BUNDLE_NAME)); + + public static final Label GROUP_SEARCH_LABEL = new Label( + new GlobalizedMessage("ui.admin.groups.search", BUNDLE_NAME)); + + public static final GlobalizedMessage SEARCH_BUTTON = new GlobalizedMessage( + "ui.admin.groups.button.search", + BUNDLE_NAME); + + public static final Label GROUP_NO_RESULTS = new Label( + new GlobalizedMessage("ui.admin.groups.searchForm.noResults", + BUNDLE_NAME)); + + public static final Label FOUND_GROUPS_TITLE = new Label( + new GlobalizedMessage("ui.admin.groups.found.title", + BUNDLE_NAME)); + + public static final Label PICK_GROUPS = new Label(new GlobalizedMessage( + "ui.admin.groups.select.explanation", + BUNDLE_NAME)); + + public static final GlobalizedMessage SAVE_BUTTON = new GlobalizedMessage( + "ui.admin.save", BUNDLE_NAME); + + public static final String SEARCH_QUERY = "query"; + + public final static String ADMIN_PAGE_URL = "/admin/"; + + public final static String ADMIN_SERVLET_PATH = "/admin/*"; + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/ApplicationsAdminTab.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/ApplicationsAdminTab.java new file mode 100644 index 000000000..da1841b59 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/ApplicationsAdminTab.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.Label; +import com.arsdigita.toolbox.ui.LayoutPanel; + +/** + * + * @author Jens Pelzetter + */ +public class ApplicationsAdminTab extends LayoutPanel { + + public ApplicationsAdminTab() { + super(); + + setLeft(new Label("Applications Admin Tab Left")); + + setBody(new Label("Applications Admin Tab Body")); + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/CategoriesAdminTab.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/CategoriesAdminTab.java new file mode 100644 index 000000000..f58211237 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/CategoriesAdminTab.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.Label; +import com.arsdigita.toolbox.ui.LayoutPanel; + +/** + * + * @author Jens Pelzetter + */ +public class CategoriesAdminTab extends LayoutPanel { + + public CategoriesAdminTab() { + super(); + + setLeft(new Label("Categories Admin Tab Left")); + + setBody(new Label("Categories Admin Tab Body")); + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/RegistryAdminTab.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/RegistryAdminTab.java new file mode 100644 index 000000000..403e3d1c9 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/RegistryAdminTab.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.Label; +import com.arsdigita.toolbox.ui.LayoutPanel; + +/** + * + * @author Jens Pelzetter + */ +public class RegistryAdminTab extends LayoutPanel { + + public RegistryAdminTab() { + super(); + + setLeft(new Label("Registry Admin Tab Left")); + + setBody(new Label("Registry Admin Tab Body")); + + } + +} diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/UsersGroupsRolesTab.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/UsersGroupsRolesTab.java new file mode 100644 index 000000000..d56922a59 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/UsersGroupsRolesTab.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.Label; +import com.arsdigita.toolbox.ui.LayoutPanel; + +/** + * + * @author Jens Pelzetter + */ +public class UsersGroupsRolesTab extends LayoutPanel { + + public UsersGroupsRolesTab() { + super(); + + setLeft(new Label("Users Groups Roles Left")); + setBody(new Label("Users Groups Roles Body")); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationException.java b/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationException.java new file mode 100644 index 000000000..eeacd2863 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationException.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 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.configuration; + +/** + * + * @author Jens Pelzetter + */ +public class ConfigurationException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of ConfigurationException without detail message. + */ + public ConfigurationException() { + super(); + } + + + /** + * Constructs an instance of ConfigurationException with the specified detail message. + * + * @param msg The detail message. + */ + public ConfigurationException(final String msg) { + super(msg); + } + + /** + * Constructs an instance of ConfigurationException which wraps the + * specified exception. + * + * @param exception The exception to wrap. + */ + public ConfigurationException(final Exception exception) { + super(exception); + } + + /** + * Constructs an instance of ConfigurationException with the specified message which also wraps the + * specified exception. + * + * @param msg The detail message. + * @param exception The exception to wrap. + */ + public ConfigurationException(final String msg, final Exception exception) { + super(msg, exception); + } +} diff --git a/ccm-core/src/main/java/org/libreccm/core/CcmCore.java b/ccm-core/src/main/java/org/libreccm/core/CcmCore.java index 50230d11f..31189aeb1 100644 --- a/ccm-core/src/main/java/org/libreccm/core/CcmCore.java +++ b/ccm-core/src/main/java/org/libreccm/core/CcmCore.java @@ -18,6 +18,9 @@ */ package org.libreccm.core; +import com.arsdigita.ui.SimplePage; +import com.arsdigita.ui.UIConfig; +import com.arsdigita.ui.UiInitializer; import com.arsdigita.ui.admin.AdminApplicationCreator; import com.arsdigita.ui.admin.AdminServlet; import com.arsdigita.ui.admin.AdminApplicationSetup; @@ -116,7 +119,6 @@ public class CcmCore implements CcmModule { @Override public void init(final InitEvent event) { - //Nothing } @Override diff --git a/ccm-core/src/main/java/org/libreccm/security/CcmShiroRealm.java b/ccm-core/src/main/java/org/libreccm/security/CcmShiroRealm.java index 8c99bf1f7..c4c92b9fd 100644 --- a/ccm-core/src/main/java/org/libreccm/security/CcmShiroRealm.java +++ b/ccm-core/src/main/java/org/libreccm/security/CcmShiroRealm.java @@ -28,6 +28,7 @@ import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; +import org.libreccm.cdi.utils.CdiUtil; import java.util.Iterator; import java.util.List; @@ -37,6 +38,7 @@ import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.CDI; +import javax.naming.InitialContext; /** * Implementation of Shiro's {@link AuthorizingRealm} to provide Shiro with the @@ -70,26 +72,34 @@ public class CcmShiroRealm extends AuthorizingRealm { if ("system-user".equals(userIdentifier)) { // The system user is a virtual user which has all roles and all // privileges +// final RoleRepository roleRepository; +// final BeanManager beanManager = CDI.current().getBeanManager(); +// final Set> beans = beanManager. +// getBeans(RoleRepository.class); +// final Iterator> iterator = beans.iterator(); +// if (iterator.hasNext()) { +// @SuppressWarnings("unchecked") +// final Bean bean +// = (Bean) iterator +// .next(); +// final CreationalContext ctx = beanManager. +// createCreationalContext(bean); +// +// roleRepository = (RoleRepository) beanManager.getReference( +// bean, RoleRepository.class, ctx); +// } else { +// throw new AuthenticationException( +// "Failed to retrieve RoleRepository"); +// } + final RoleRepository roleRepository; - final BeanManager beanManager = CDI.current().getBeanManager(); - final Set> beans = beanManager. - getBeans(RoleRepository.class); - final Iterator> iterator = beans.iterator(); - if (iterator.hasNext()) { - @SuppressWarnings("unchecked") - final Bean bean - = (Bean) iterator. - next(); - final CreationalContext ctx = beanManager. - createCreationalContext(bean); - - roleRepository = (RoleRepository) beanManager.getReference( - bean, RoleRepository.class, ctx); - } else { + try { + roleRepository = CdiUtil.createCdiUtil() + .findBean(RoleRepository.class); + } catch (IllegalStateException ex) { throw new AuthenticationException( - "Failed to retrieve RoleRepository"); + "Failed to retrieve RoleRepository", ex); } - final List roles = roleRepository.findAll(); final SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); @@ -182,28 +192,36 @@ public class CcmShiroRealm extends AuthorizingRealm { // For some reason we can't use the the CdiUtil class here, therefore // we have to do the lookup for the UserRepository be ourself. final UserRepository userRepository; - final BeanManager beanManager = CDI.current().getBeanManager(); - final Set> beans = beanManager.getBeans( - UserRepository.class); - final Iterator> iterator = beans.iterator(); - if (iterator.hasNext()) { - @SuppressWarnings("unchecked") - final Bean bean = (Bean) iterator - .next(); - final CreationalContext ctx = beanManager - .createCreationalContext(bean); - - userRepository = (UserRepository) beanManager.getReference( - bean, UserRepository.class, ctx); - } else { +// final BeanManager beanManager = CDI.current().getBeanManager(); +// final Set> beans = beanManager.getBeans( +// UserRepository.class); +// final Iterator> iterator = beans.iterator(); +// if (iterator.hasNext()) { +// @SuppressWarnings("unchecked") +// final Bean bean = (Bean) iterator +// .next(); +// final CreationalContext ctx = beanManager +// .createCreationalContext(bean); +// +// userRepository = (UserRepository) beanManager.getReference( +// bean, UserRepository.class, ctx); + try { + userRepository = CdiUtil.createCdiUtil().findBean( + UserRepository.class); + } catch (IllegalStateException ex) { throw new AuthenticationException( - "Failed to retrieve UserRepository."); + "Failed to retrieve UserRepository.", ex); } +// } else { +// throw new AuthenticationException( +// "Failed to retrieve UserRepository."); +// } // Depending of the configuration of CCM use the appropriate method // for finding the user in the database. final KernelConfig config = KernelConfig.getConfig(); final User user; + if ("email".equals(config.getPrimaryUserIdentifier())) { user = userRepository.findByEmailAddress(userIdentifier); } else { @@ -211,7 +229,8 @@ public class CcmShiroRealm extends AuthorizingRealm { } // If no matching user is found throw an AuthenticationException - if (user == null) { + if (user + == null) { throw new AuthenticationException(String.format( "No user identified by principal \"%s\" was found. Primary user " + "identifier is \"%s\".", @@ -219,6 +238,7 @@ public class CcmShiroRealm extends AuthorizingRealm { } return user; + } /** diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/UIResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources.properties new file mode 100755 index 000000000..a4c5e6e97 --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources.properties @@ -0,0 +1,31 @@ +ui.admin.access_denied=Access Denied +ui.admin.nusers=nUsers +ui.admin.help=Help +ui.admin.signout=Sign out +ui.admin.portal=My Portal +ui.admin.greeting=Welcome +ui.sitemap.site_node=Site Node: +ui.sitemap.mounted_instance=Mounted Instance: +ui.sitemap.enter_new_node_name_in_text_field=Enter new Node name in text field. +ui.sitemap.are_you_sure_you_want_to_remove_this_node=Are you sure you want to remove this node? +ui.sitemap.are_you_sure_you_want_to_umount_this_instance=Are you sure you want to umount this instance? +ui.sitemap.enter_name_for_new_package_instance_in_text_field_then_select_a_package_to_mount_from_list=Enter name for new package instance in text field, then select a package to mount from list. +ui.sitemap.h4sitemap_treeh4=

SiteMap Tree

+ui.sitemap.configure_sitemap_admin_page=Configure SiteMap Admin Page +ui.sitemap.h4emselect_sitenode_to_view_detailsemh4=

Select SiteNode to View Details

+ui.sitemap.configuration_menu_placeholder=Configuration Menu Placeholder +ui.sitemap.access_denied_to_sitemap=Access Denied to SiteMap +ui.debug.transform.on=Display transformation +ui.debug.transform.off=Hide transformation +ui.debug.xml=View document XML +ui.debug.xsl=Download XSL files +com.arsdigita.ui.admin.applications.tree.heading=Applications +com.arsdigita.ui.admin.applications.url.validation.not_blank=The URL of an application instance can is mandatory. +com.arsdigita.ui.admin.applications.url.valiation.minmaxlength=The length of an URL of an application instance must be between 1 and 100 characters. +com.arsdigita.ui.admin.applications.title.validation.not_blank=Title is mandatory for an application instance. +com.arsdigita.ui.admin.applications.title.valiation.minmaxlength=The minimum length of the title of an applicatio instance is one character, the maximum length are 200 characters +com.arsdigita.ui.admin.applications.desc.valiation.minmaxlength=The maximum length of a descrption of an application instance are 4000 characters. +com.arsdigita.ui.admin.applications.url.label=URL +com.arsdigita.ui.admin.applications.title.label=Title +com.arsdigita.ui.admin.applications.desc.label=Description +ui.change_password=Change password diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_de.properties new file mode 100644 index 000000000..66904d78a --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_de.properties @@ -0,0 +1,31 @@ +ui.admin.access_denied=Zugang abgelehnt +ui.admin.nusers=nUsers +ui.admin.help=Hilfe +ui.admin.signout=Abmelden +ui.admin.portal=Meine Startseite +ui.admin.greeting=Willkommen +ui.sitemap.site_node=Site Node: +ui.sitemap.mounted_instance=Verf\u00fcgbare Instanz\: +ui.sitemap.enter_new_node_name_in_text_field=Tragen Sie einen neuen Namen im Textfeld ein. +ui.sitemap.are_you_sure_you_want_to_remove_this_node=Sind Sie sicher, diesen Knoten zu entfernen? +ui.sitemap.are_you_sure_you_want_to_umount_this_instance=Sind Sie sicher, diese Instanz auszuh\u00e4ngen? +ui.sitemap.enter_name_for_new_package_instance_in_text_field_then_select_a_package_to_mount_from_list=Enter name for new package instance in text field, then select a package to mount from list. +ui.sitemap.h4sitemap_treeh4=

SiteMap Tree

+ui.sitemap.configure_sitemap_admin_page=Configure SiteMap Admin Page +ui.sitemap.h4emselect_sitenode_to_view_detailsemh4=

Knoten f\u00fcr die Detailansicht w\u00e4hlen

+ui.sitemap.configuration_menu_placeholder=Configuration Menu Placeholder +ui.sitemap.access_denied_to_sitemap=Zugang zur SiteMap abgelehnt. +ui.debug.transform.on=Transformation anzeigen +ui.debug.transform.off=Transformation verbergen +ui.debug.xml=XML Dokument ansehen +ui.debug.xsl=Download XSL Dateien +com.arsdigita.ui.admin.applications.tree.heading=Applikationen +com.arsdigita.ui.admin.applications.url.validation.not_blank=Die Angabe einer URL ist erforderlich +com.arsdigita.ui.admin.applications.url.valiation.minmaxlength=Die URL einer Applikations-Instanz muss zwischen einem und 100 Zeichen lang sein +com.arsdigita.ui.admin.applications.title.validation.not_blank=Der Titel ist f\u00fcr das Anlegen einer Applikations-Instanz erforderlich +com.arsdigita.ui.admin.applications.title.valiation.minmaxlength=Der Titel einer Applikations-Instanz muss zwischen einem und 200 Zeichen lang sein. +com.arsdigita.ui.admin.applications.desc.valiation.minmaxlength=Die Beschreibung einer Applikations-Instanz darf max. 4000 Zeichen lang sein +com.arsdigita.ui.admin.applications.url.label=URL +com.arsdigita.ui.admin.applications.title.label=Bezeichnung +com.arsdigita.ui.admin.applications.desc.label=Beschreibung +ui.change_password=Passwort \u00e4ndern diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_en.properties new file mode 100755 index 000000000..1c13aa6af --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_en.properties @@ -0,0 +1,31 @@ +ui.admin.access_denied=Access Denied +ui.admin.nusers=nUsers +ui.admin.help=Help +ui.admin.signout=Sign out +ui.admin.portal=My Portal +ui.admin.greeting=Welcome +ui.sitemap.site_node=Site Node: +ui.sitemap.mounted_instance=Mounted Instance: +ui.sitemap.enter_new_node_name_in_text_field=Enter new Node name in text field. +ui.sitemap.are_you_sure_you_want_to_remove_this_node=Are you sure you want to remove this node? +ui.sitemap.are_you_sure_you_want_to_umount_this_instance=Are you sure you want to umount this instance? +ui.sitemap.enter_name_for_new_package_instance_in_text_field_then_select_a_package_to_mount_from_list=Enter name for new package instance in text field, then select a package to mount from list. +ui.sitemap.h4sitemap_treeh4=

SiteMap Tree

+ui.sitemap.configure_sitemap_admin_page=Configure SiteMap Admin Page +ui.sitemap.h4emselect_sitenode_to_view_detailsemh4=

Select SiteNode to View Details

+ui.sitemap.configuration_menu_placeholder=Configuration Menu Placeholder +ui.sitemap.access_denied_to_sitemap=Access Denied to SiteMap +ui.debug.transform.on=Display transformation +ui.debug.transform.off=Hide transformation +ui.debug.xml=View document XML +ui.debug.xsl=Download XSL files +com.arsdigita.ui.admin.applications.tree.heading=Applications +com.arsdigita.ui.admin.applications.url.validation.not_blank= +com.arsdigita.ui.admin.applications.url.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.title.validation.not_blank= +com.arsdigita.ui.admin.applications.title.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.desc.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.url.label= +com.arsdigita.ui.admin.applications.title.label= +com.arsdigita.ui.admin.applications.desc.label= +ui.change_password= diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_fr.properties new file mode 100755 index 000000000..cc00b5460 --- /dev/null +++ b/ccm-core/src/main/resources/com/arsdigita/ui/UIResources_fr.properties @@ -0,0 +1,27 @@ +ui.admin.access_denied=Acc\u00e8s refus\u00e9 +ui.admin.help=Aide +ui.admin.signout=se deconnecter +ui.admin.portal=Ma Porte +ui.admin.greeting=Bienvenue +ui.admin.nusers=TRANSLATE THIS: nUsers (ui.admin.nusers) +ui.sitemap.site_node=TRANSLATE THIS: Site Node: (ui.sitemap.site_node) +ui.sitemap.mounted_instance=TRANSLATE THIS: Mounted Instance: (ui.sitemap.mounted_instance) +ui.sitemap.enter_new_node_name_in_text_field=TRANSLATE THIS: Enter new Node name in text field. (ui.sitemap.enter_new_node_name_in_text_field) +ui.sitemap.are_you_sure_you_want_to_remove_this_node=TRANSLATE THIS: Are you sure you want to remove this node? (ui.sitemap.are_you_sure_you_want_to_remove_this_node) +ui.sitemap.are_you_sure_you_want_to_umount_this_instance=TRANSLATE THIS: Are you sure you want to umount this instance? (ui.sitemap.are_you_sure_you_want_to_umount_this_instance) +ui.sitemap.enter_name_for_new_package_instance_in_text_field_then_select_a_package_to_mount_from_list=TRANSLATE THIS: Enter name for new package instance in text field, then select a package to mount from list. (ui.sitemap.enter_name_for_new_package_instance_in_text_field_then_select_a_package_to_mount_from_list) +ui.sitemap.h4sitemap_treeh4=

Plan du site

+ui.sitemap.configure_sitemap_admin_page=TRANSLATE THIS: Configure SiteMap Admin Page (ui.sitemap.configure_sitemap_admin_page) +ui.sitemap.h4emselect_sitenode_to_view_detailsemh4=TRANSLATE THIS:

Select SiteNode to View Details

(ui.sitemap.h4emselect_sitenode_to_view_detailsemh4) +ui.sitemap.configuration_menu_placeholder=TRANSLATE THIS: Configuration Menu Placeholder (ui.sitemap.configuration_menu_placeholder) +ui.sitemap.access_denied_to_sitemap=Vous n'avez pas acc\u00e8s au plan du site +com.arsdigita.ui.admin.applications.tree.heading= +com.arsdigita.ui.admin.applications.url.validation.not_blank= +com.arsdigita.ui.admin.applications.url.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.title.validation.not_blank= +com.arsdigita.ui.admin.applications.title.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.desc.valiation.minmaxlength= +com.arsdigita.ui.admin.applications.url.label= +com.arsdigita.ui.admin.applications.title.label= +com.arsdigita.ui.admin.applications.desc.label= +ui.change_password= diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index 554dde715..646aa2e81 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -152,3 +152,6 @@ ui.admin.sysinfo.xml_config=XML config ui.admin.groups.ID_is_null=ID is null ui.admin.user.userpasswordform.retrieving_user_failed=Failed to retrieve user ui.admin.groups.couldnt_find_specified_group=Couldn't find the specified group +ui.admin.tab.users_groups_roles.title=Users/Groups/Roles +ui.admin.tab.categories.title=Categories +ui.admin.tab.registry.title=Registry diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index 565b29c03..cde5bc1b2 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -152,3 +152,6 @@ ui.admin.sysinfo.xml_config=XML Konfiguration ui.admin.groups.ID_is_null=ID is null ui.admin.user.userpasswordform.retrieving_user_failed=Konnte Benutzer nicht abrufen ui.admin.groups.couldnt_find_specified_group=Konnte die spezifische Gruppe nicht finden +ui.admin.tab.users_groups_roles.title=Benutzer/Gruppen/Rollen +ui.admin.tab.categories.title=Kategorien +ui.admin.tab.registry.title=Registry diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index bfd1b014a..405a4b6b9 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -110,3 +110,6 @@ ui.admin.cancel_msg=Submission cancelled ui.admin.groups.ID_is_null=ID is null ui.admin.user.userpasswordform.retrieving_user_failed=Failed to retrieve user ui.admin.groups.couldnt_find_specified_group=Couldn't find the specified group +ui.admin.tab.users_groups_roles.title=Users/Groups/Roles +ui.admin.tab.categories.title=Categories +ui.admin.tab.registry.title=Registry diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index 8b2fcb595..906f8593d 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -95,3 +95,6 @@ ui.admin.cancel_msg=Submission cancelled ui.admin.groups.ID_is_null= ui.admin.user.userpasswordform.retrieving_user_failed=Impossible de retrouver l'utilisateur ui.admin.groups.couldnt_find_specified_group=Impossible de trouver le groupe sp\u00e9cifi\u00e9 +ui.admin.tab.users_groups_roles.title= +ui.admin.tab.categories.title= +ui.admin.tab.registry.title= diff --git a/ccm-docrepo/src/main/java/org/libreccm/docrepo/AbstractResourceRepository.java b/ccm-docrepo/src/main/java/org/libreccm/docrepo/AbstractResourceRepository.java index 8c5fa1abf..839ff9588 100644 --- a/ccm-docrepo/src/main/java/org/libreccm/docrepo/AbstractResourceRepository.java +++ b/ccm-docrepo/src/main/java/org/libreccm/docrepo/AbstractResourceRepository.java @@ -18,7 +18,6 @@ */ package org.libreccm.docrepo; - import org.libreccm.auditing.AbstractAuditedEntityRepository; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.security.PermissionChecker; @@ -32,13 +31,15 @@ import java.util.List; import java.util.stream.Collectors; /** - * Repository class for retrieving, storing and deleting {@code AbstractResource}s. + * Repository class for retrieving, storing and deleting + * {@code AbstractResource}s. * * @author Tobias Osmers * @version 01/10/2015 */ -public abstract class AbstractResourceRepository extends - AbstractAuditedEntityRepository { +public abstract class AbstractResourceRepository + extends + AbstractAuditedEntityRepository { protected Class classOfT; @@ -64,29 +65,33 @@ public abstract class AbstractResourceRepository ext } /** - * Checks if the current subject has permissions grating him the - * privilege to read the requested {@link AbstractResource}(s) and removes the - * ones he is not allowed to access. + * Checks if the current subject has permissions grating him the privilege + * to read the requested {@link AbstractResource}(s) and removes the ones he + * is not allowed to access. * - * @param resources The requested {@link AbstractResource}s, found in the database - * @return A list of {@link AbstractResource}s the subject is allowed to access + * @param resources The requested {@link AbstractResource}s, found in the + * database + * + * @return A list of {@link AbstractResource}s the subject is allowed to + * access */ private List permissionFilter(List resources) { - final CdiUtil cdiUtil = new CdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); + final PermissionChecker permissionChecker = CdiUtil.createCdiUtil() + .findBean(PermissionChecker.class); return resources.stream().filter(resource -> permissionChecker - .isPermitted("read", resource)).collect(Collectors.toList()); + .isPermitted("read", resource)).collect(Collectors.toList()); } /** - * Checks if the current subject has permissions grating him the - * privilege to read the one requested {@link AbstractResource} and removes it if - * he is not allowed to access. + * Checks if the current subject has permissions grating him the privilege + * to read the one requested {@link AbstractResource} and removes it if he + * is not allowed to access. * - * @param resource The requested {@link AbstractResource}, found in the database - * @return A list of at most one {@link AbstractResource} the subject is allowed to - * access + * @param resource The requested {@link AbstractResource}, found in the + * database + * + * @return A list of at most one {@link AbstractResource} the subject is + * allowed to access */ private T permissionFilter(T resource) { return permissionFilter(Collections.singletonList(resource)).get(0); @@ -96,19 +101,20 @@ public abstract class AbstractResourceRepository ext * Retrieve all {@link AbstractResource}s with the given name. * * @param name The name for the searched {@link AbstractResource} - * @return The {@link AbstractResource}s with the given name, if there aren't - * any an {@code EmptyList} + * + * @return The {@link AbstractResource}s with the given name, if there + * aren't any an {@code EmptyList} */ public List findByName(final String name) { final TypedQuery query = getFindByNameQuery(); - query.setParameter("name", name); + query.setParameter("name", name); return permissionFilter(query.getResultList()); } /** - * Abstract method to get a {@link TypedQuery}, specifically implemented - * in the subclasses matching their own database requests, finding the + * Abstract method to get a {@link TypedQuery}, specifically implemented in + * the subclasses matching their own database requests, finding the * {@code T}-typed objects by name. * * @return A {@link TypedQuery} to find objects by name @@ -118,10 +124,11 @@ public abstract class AbstractResourceRepository ext /** * Retrieve a {@code AbstractResource} by its {@code path}. * - * @param pathName The {@code path} to the {@code AbstractResource}. + * @param pathName The {@code path} to the {@code AbstractResource}. * - * @return The {@code AbstractResource} identified by the given {@code path}, if - * there is such a {@code AbstractResource}, {@code null} if not. + * @return The {@code AbstractResource} identified by the given + * {@code path}, if there is such a {@code AbstractResource}, + * {@code null} if not. */ public T findByPathName(final String pathName) { final TypedQuery query = getFindByPathNameQuery(); @@ -131,8 +138,8 @@ public abstract class AbstractResourceRepository ext } /** - * Abstract method to get a {@link TypedQuery}, specifically implemented - * in the subclasses matching their own database requests, finding the + * Abstract method to get a {@link TypedQuery}, specifically implemented in + * the subclasses matching their own database requests, finding the * {@code T}-typed objects by path name. * * @return A {@link TypedQuery} to find objects by path name @@ -142,10 +149,12 @@ public abstract class AbstractResourceRepository ext /** * Retrieve the {@code AbstractResource}s, a given {@link User} created. * - * @param creator The {@link User}, who created the {@code AbstractResource}s. + * @param creator The {@link User}, who created the + * {@code AbstractResource}s. * - * @return The {@code AbstractResource}s, created by the given {@link User}, if - * there are such {@code AbstractResource}s, {@code EmptyList} if not. + * @return The {@code AbstractResource}s, created by the given {@link User}, + * if there are such {@code AbstractResource}s, {@code EmptyList} if + * not. */ public List findForCreator(final User creator) { final TypedQuery query = getFindForCreatorQuery(); @@ -155,8 +164,8 @@ public abstract class AbstractResourceRepository ext } /** - * Abstract method to get a {@link TypedQuery}, specifically implemented - * in the subclasses matching their own database requests, finding the + * Abstract method to get a {@link TypedQuery}, specifically implemented in + * the subclasses matching their own database requests, finding the * {@code T}-typed objects created by a given/set {@link User}. * * @return A {@link TypedQuery} to find objects for creator. @@ -164,12 +173,15 @@ public abstract class AbstractResourceRepository ext protected abstract TypedQuery getFindForCreatorQuery(); /** - * Retrieve the {@code AbstractResource}s, a given {@link User} last modified. + * Retrieve the {@code AbstractResource}s, a given {@link User} last + * modified. * - * @param modifier The {@link User} who last modified the {@code AbstractResource}s. + * @param modifier The {@link User} who last modified the + * {@code AbstractResource}s. * - * @return The {@code AbstractResource}s, last modified by the given {@link User}, - * if there are such {@code AbstractResource}s, {@code EmptyList} if not. + * @return The {@code AbstractResource}s, last modified by the given + * {@link User}, if there are such {@code AbstractResource}s, + * {@code EmptyList} if not. */ public List findForModifier(final User modifier) { final TypedQuery query = getFindForModifierQuery(); @@ -179,11 +191,12 @@ public abstract class AbstractResourceRepository ext } /** - * Abstract method to get a {@link TypedQuery}, specifically implemented - * in the subclasses matching their own database requests, finding the + * Abstract method to get a {@link TypedQuery}, specifically implemented in + * the subclasses matching their own database requests, finding the * {@code T}-typed objects last modified for a given/set {@link User}. * * @return A {@link TypedQuery} to find objects for last modifier. */ protected abstract TypedQuery getFindForModifierQuery(); + } diff --git a/ccm-docrepo/src/main/java/org/libreccm/docrepo/RepositoryRepository.java b/ccm-docrepo/src/main/java/org/libreccm/docrepo/RepositoryRepository.java index 2c1a5916a..b2b69fceb 100644 --- a/ccm-docrepo/src/main/java/org/libreccm/docrepo/RepositoryRepository.java +++ b/ccm-docrepo/src/main/java/org/libreccm/docrepo/RepositoryRepository.java @@ -38,7 +38,7 @@ import java.util.stream.Collectors; */ @RequestScoped public class RepositoryRepository extends - AbstractAuditedEntityRepository { + AbstractAuditedEntityRepository { @Inject private EntityManager entityManager; @@ -62,19 +62,21 @@ public class RepositoryRepository extends } /** - * Checks if the current subject has permissions grating him the - * privilege to read the requested {@link Repository}(s) and removes the - * ones he is not allowed to access. + * Checks if the current subject has permissions grating him the privilege + * to read the requested {@link Repository}(s) and removes the ones he is + * not allowed to access. * - * @param repositories The requested {@link AbstractResource}s, found in the database - * @return A list of {@link AbstractResource}s the subject is allowed to access + * @param repositories The requested {@link AbstractResource}s, found in the + * database + * + * @return A list of {@link AbstractResource}s the subject is allowed to + * access */ private List permissionFilter(List repositories) { - final CdiUtil cdiUtil = new CdiUtil(); - final PermissionChecker permissionChecker = cdiUtil.findBean( - PermissionChecker.class); + final PermissionChecker permissionChecker = CdiUtil.createCdiUtil() + .findBean(PermissionChecker.class); return repositories.stream().filter(repository -> permissionChecker - .isPermitted("read", repository)).collect(Collectors.toList()); + .isPermitted("read", repository)).collect(Collectors.toList()); } /** @@ -86,7 +88,7 @@ public class RepositoryRepository extends */ public List findForOwner(User owner) { final TypedQuery query = entityManager.createNamedQuery( - "DocRepo.findRepositoriesForOwner", Repository.class); + "DocRepo.findRepositoriesForOwner", Repository.class); query.setParameter("owner", owner); return permissionFilter(query.getResultList()); diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutForm.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutForm.java index 89cba2b28..3b1486e6e 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutForm.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutForm.java @@ -161,9 +161,9 @@ public class ShortcutForm extends Form { @Override public void init(FormSectionEvent ev) throws FormProcessException { final PageState state = ev.getPageState(); - final CdiUtil cdiUtil = new CdiUtil(); - final ShortcutRepository shortcutsRepo = cdiUtil.findBean(ShortcutRepository.class); - + final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil() + .findBean(ShortcutRepository.class); + Long shortcutKey = (Long) m_selected_shortcut .getSelectedKey(state); if (shortcutKey == null) { @@ -222,8 +222,8 @@ public class ShortcutForm extends Form { public void process(FormSectionEvent e) throws FormProcessException { ShortcutManager shortcutMgr = new ShortcutManager(); PageState state = e.getPageState(); - final CdiUtil cdiUtil = new CdiUtil(); - final ShortcutRepository shortcutsRepo = cdiUtil.findBean(ShortcutRepository.class); + final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil() + .findBean(ShortcutRepository.class); Long shortcutKey = (Long) m_selected_shortcut.getSelectedKey(state); diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutsTable.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutsTable.java index b085f2e4b..1c06adce5 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutsTable.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ui/ShortcutsTable.java @@ -56,9 +56,8 @@ public class ShortcutsTable extends Table { public ShortcutsTable(final ParameterSingleSelectionModel selected_shortcut) { super(new ShortcutsModelBuilder(), headers); setDefaultCellRenderer(new ShortcutsCellRenderer()); - final CdiUtil cdiUtil = new CdiUtil(); - final ShortcutRepository shortcutsRepo = cdiUtil.findBean( - ShortcutRepository.class); + final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil() + .findBean(ShortcutRepository.class); addTableActionListener(new TableActionListener() {