From 21633451bc895821d4ca5e37afe7c300471ca98c Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Thu, 26 Nov 2020 21:42:35 +0100 Subject: [PATCH] Admin UI for Applications --- .../applications/ApplicationController.java | 2 + .../applications/ApplicationTypeInfoItem.java | 10 ++ .../applications/ApplicationsController.java | 67 +++++++-- .../admin/applications/ApplicationsPage.java | 16 +- ...r.java => IsApplicationControllerFor.java} | 23 ++- .../org/libreccm/web/ApplicationType.java | 7 +- .../admin/applications/applicationtypes.xhtml | 10 +- .../org/libreccm/ui/AdminBundle.properties | 1 + .../org/libreccm/ui/AdminBundle_de.properties | 1 + ccm-shortcuts/pom.xml | 15 ++ .../shortcuts/ShortcutAdminMessages.java | 141 ++++++++++++++++++ .../ShortcutsApplicationController.java | 58 +++++++ .../applications/shortcuts/shortcuts.xhtml | 67 +++++++++ .../shortcuts/ShortcutsResources.properties | 1 + .../ShortcutsResources_de.properties | 1 + 15 files changed, 397 insertions(+), 23 deletions(-) rename ccm-core/src/main/java/org/libreccm/ui/admin/applications/{DefaultApplicationController.java => IsApplicationControllerFor.java} (65%) create mode 100644 ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java create mode 100644 ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java create mode 100644 ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationController.java index f18aa74d6..798f71912 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationController.java @@ -24,4 +24,6 @@ package org.libreccm.ui.admin.applications; */ public interface ApplicationController { + String getApplication(); + } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java index 6c58dca64..b598f9e66 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java @@ -36,6 +36,8 @@ public class ApplicationTypeInfoItem implements private boolean singleton; private long numberOfInstances; + + private String controllerLink; protected ApplicationTypeInfoItem() { // Nothing @@ -80,6 +82,14 @@ public class ApplicationTypeInfoItem implements protected void setNumberOfInstances(final long numberOfInstances) { this.numberOfInstances = numberOfInstances; } + + public String getControllerLink() { + return controllerLink; + } + + protected void setControllerLink(final String controllerLink) { + this.controllerLink = controllerLink; + } @Override public int compareTo(final ApplicationTypeInfoItem other) { diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java index 720442830..531abaf94 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java @@ -32,12 +32,15 @@ import java.util.Map; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.enterprise.util.AnnotationLiteral; import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; +import javax.mvc.MvcContext; import javax.ws.rs.GET; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; /** * @@ -50,16 +53,23 @@ public class ApplicationsController { @Inject private ApplicationManager appManager; - + @Inject private ApplicationRepository appRepository; @Inject private GlobalizationHelper globalizationHelper; - + @Inject private Models models; + @Inject + private MvcContext mvc; + + @Inject + @Any + private Instance applicationControllers; + @GET @Path("/") @AuthorizationRequired @@ -73,22 +83,12 @@ public class ApplicationsController { .map(this::buildTypeInfoItem) .sorted() .collect(Collectors.toList()); - + models.put("applicationTypes", appTypes); return "org/libreccm/ui/admin/applications/applicationtypes.xhtml"; } - @GET - @Path("/{type}") - @AuthorizationRequired - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - public String getApplicationInstances( - @PathParam("type") final String type - ) { - throw new UnsupportedOperationException(); - } - private ApplicationTypeInfoItem buildTypeInfoItem( final ApplicationType applicationType ) { @@ -104,7 +104,46 @@ public class ApplicationsController { appRepository.findByType(applicationType.name()).size() ); + final IsApplicationControllerForLiteral literal + = new IsApplicationControllerForLiteral(applicationType.name()); + + final Instance instance = applicationControllers + .select(literal); + + if (instance.isResolvable()) { + final ApplicationController controller = instance.get(); + item.setControllerLink( + mvc.uri( + String.format( + "%s#getApplication", + controller.getClass().getSimpleName() + ) + ).toString() + ); + } + return item; } + private class IsApplicationControllerForLiteral + extends AnnotationLiteral + implements IsApplicationControllerFor { + + private static final long serialVersionUID = 1L; + + private final String value; + + public IsApplicationControllerForLiteral( + final String value + ) { + this.value = value; + } + + @Override + public String value() { + return value; + } + + } + } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java index 48a7677c3..04ea09731 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java @@ -25,6 +25,9 @@ import java.util.HashSet; import java.util.Set; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; /** * @@ -33,17 +36,28 @@ import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationsPage implements AdminPage { + @Inject + @Any + private Instance applicationControllers; + @Override public Set> getControllerClasses() { final Set> classes = new HashSet<>(); classes.add(ApplicationsController.class); + + applicationControllers + .stream() + .map(controller -> controller.getClass()) + .forEach(classes::add); + return classes; } @Override public String getUriIdentifier() { return String.format( - "%s#getApplicationTypes", ApplicationsController.class.getSimpleName() + "%s#getApplicationTypes", ApplicationsController.class + .getSimpleName() ); } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java similarity index 65% rename from ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java rename to ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java index 7f76e96a7..a6921d67d 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java @@ -18,10 +18,31 @@ */ package org.libreccm.ui.admin.applications; +import org.libreccm.web.CcmApplication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + /** * * @author Jens Pelzetter */ -public class DefaultApplicationController implements ApplicationController { +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target( + { + ElementType.METHOD, + ElementType.FIELD, + ElementType.PARAMETER, + ElementType.TYPE + } +) +public @interface IsApplicationControllerFor { + + String value(); } diff --git a/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java b/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java index 285b56225..9d663c2ee 100644 --- a/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java +++ b/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java @@ -23,9 +23,6 @@ import com.arsdigita.ui.admin.applications.AbstractAppSettingsPane; import com.arsdigita.ui.admin.applications.DefaultApplicationInstanceForm; import com.arsdigita.ui.admin.applications.DefaultApplicationSettingsPane; -import org.libreccm.ui.admin.applications.ApplicationController; -import org.libreccm.ui.admin.applications.DefaultApplicationController; - import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -119,9 +116,7 @@ public @interface ApplicationType { Class creator(); Class instanceForm() default DefaultApplicationInstanceForm.class; - - Class adminController() default DefaultApplicationController.class; - + Class settingsPane() default DefaultApplicationSettingsPane.class; } diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/applicationtypes.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/applicationtypes.xhtml index 15c80fe63..a66f89d76 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/applicationtypes.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/applicationtypes.xhtml @@ -23,13 +23,21 @@
  • - ${type.title} + + #{type.title} + + + #{type.title} +

    #{AdminMessages['applications.types.singleton']} + + #{AdminMessages.getMessage('applications.number_of_instances_one', [type.numberOfInstances])} + #{AdminMessages.getMessage('applications.number_of_instances', [type.numberOfInstances])} diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties index 90332823f..7bf9becf9 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties @@ -492,3 +492,4 @@ sites.form.buttons.create=Create Site sites.form.buttons.save=Save applications.types.singleton=Singleton applications.number_of_instances={0} instances +applications.number_of_instances_one={0} instance diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties index b4410ea95..3829640f5 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties @@ -492,3 +492,4 @@ sites.form.buttons.create=Site anlegen sites.form.buttons.save=Speichern applications.types.singleton=Singleton applications.number_of_instances={0} Instanzen +applications.number_of_instances_one={0} instance diff --git a/ccm-shortcuts/pom.xml b/ccm-shortcuts/pom.xml index ef64710d5..92b3992c7 100644 --- a/ccm-shortcuts/pom.xml +++ b/ccm-shortcuts/pom.xml @@ -73,6 +73,21 @@ provided + + javax.mvc + javax.mvc-api + + + org.eclipse.krazo + krazo-core + provided + + + org.eclipse.krazo.ext + krazo-freemarker + provided + + com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider diff --git a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java new file mode 100644 index 000000000..0d65d7cd1 --- /dev/null +++ b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutAdminMessages.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2020 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.admin.applications.shortcuts; + +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.shortcuts.ShortcutsConstants; +import org.libreccm.ui.admin.AdminConstants; + +import java.text.MessageFormat; +import java.util.AbstractMap; +import java.util.List; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("ShortcutAdminMessages") +public class ShortcutAdminMessages extends AbstractMap { + + /** + * Provides access to the locale negoiated by LibreCCM. + */ + @Inject + private GlobalizationHelper globalizationHelper; + + /** + * The {@link ResourceBundle} to use. + */ + private ResourceBundle messages; + + /** + * Loads the resource bundle. + */ + @PostConstruct + private void init() { + messages = ResourceBundle.getBundle( + ShortcutsConstants.SHORTCUTS_BUNDLE, + globalizationHelper.getNegotiatedLocale() + ); + } + + /** + * Retrieves a message from the resource bundle. + * + * @param key The key of the message. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage(final String key) { + if (messages.containsKey(key)) { + return messages.getString(key); + } else { + return String.format("???%s???", key); + } + } + + /** + * Retrieves a message with placeholders. + * + * @param key The key of the message. + * @param parameters The parameters for the placeholders. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage( + final String key, final List parameters + ) { + return getMessage(key, parameters.toArray()); + } + + /** + * The translated message or {@code ???message???} if the the key is not + * found in the resource bundle (message is replaced with the key). + * + * @param key The key of the message. + * @param parameters The parameters for the placeholders. + * + * @return The translated message or {@code ???message???} if the the key is + * not found in the resource bundle (message is replaced with the + * key). + */ + public String getMessage( + final String key, final Object[] parameters + ) { + if (messages.containsKey(key)) { + return MessageFormat.format(messages.getString(key), parameters); + } else { + return String.format("???%s???", key); + } + } + + @Override + public String get(final Object key) { + return get((String) key); + } + + public String get(final String key) { + return getMessage(key); + } + + @Override + public Set> entrySet() { + return messages + .keySet() + .stream() + .collect( + Collectors.toMap(key -> key, key -> messages.getString(key)) + ) + .entrySet(); + } + +} diff --git a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java new file mode 100644 index 000000000..101a60b0c --- /dev/null +++ b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 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.admin.applications.shortcuts; + +import org.libreccm.shortcuts.ShortcutRepository; +import org.libreccm.shortcuts.ShortcutsConstants; +import org.libreccm.ui.admin.applications.ApplicationController; +import org.libreccm.ui.admin.applications.IsApplicationControllerFor; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Controller +//@IsApplicationControllerFor(ShortcutsConstants.SHORTCUTS_APP_TYPE) +@Path("/application") +public class ShortcutsApplicationController implements ApplicationController { + + @Inject + private Models models; + + @Inject + private ShortcutRepository shortcutRepository; + + @GET + @Path("/") + @Override + public String getApplication() { + models.put("shortcuts", shortcutRepository.findAll()); + + return "org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml"; + } + +} diff --git a/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml b/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml new file mode 100644 index 000000000..4b6e0f517 --- /dev/null +++ b/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + +
    +

    #{ShortcutAdminMessages['application_title']}

    + + + + + + + + + + + + + + + + + + + + +
    #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_url_key.header']}#{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_redirect.header']}#{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_actions.header']}
    #{shortcut.urlKey}#{shortcut.redirect} + + + #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.edit']} + + + + + #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.delete']} + +
    +
    +
    +
    + + diff --git a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties index 38469b544..23af7122d 100644 --- a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties +++ b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties @@ -19,6 +19,7 @@ application_title=Shortcuts application_desc=Manage short URLs for internal and external redirects. shortcuts.ui.admin.shortcuts_table.col_url_key.header=URL shortcuts.ui.admin.shortcuts_table.col_redirect.header=Redirect +shortcuts.ui.admin.shortcuts_table.col_actions.header=Actions shortcuts.ui.admin.shortcuts_table.col_edit.header=Edit shortcuts.ui.admin.shortcuts_table.col_delete.header=Delete shortcuts.ui.admin.shortcuts_table.edit=Edit diff --git a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties index 1fefabf78..5d3b1aaae 100644 --- a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties +++ b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties @@ -32,3 +32,4 @@ shortcuts.ui.admin.redirect.error.invalid=Das Ziel der Weiterleitung muss eine a shortcuts.ui.admin.heading=Shortcuts verwalten shortcuts.ui.admin.table.empty=Es wurden noch keine Shortcuts angelegt. shortcuts.ui.admin.add_shortcut=Shortcut hinzuf\u00fcgen +shortcuts.ui.admin.shortcuts_table.col_actions.header=Aktionen