diff --git a/ccm-core/src/com/arsdigita/ui/UIResources.properties b/ccm-core/src/com/arsdigita/ui/UIResources.properties index ff63cc0cf..2e4db4681 100755 --- a/ccm-core/src/com/arsdigita/ui/UIResources.properties +++ b/ccm-core/src/com/arsdigita/ui/UIResources.properties @@ -19,3 +19,12 @@ 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 diff --git a/ccm-core/src/com/arsdigita/ui/UIResources_de.properties b/ccm-core/src/com/arsdigita/ui/UIResources_de.properties index dc2d53275..6e925603b 100644 --- a/ccm-core/src/com/arsdigita/ui/UIResources_de.properties +++ b/ccm-core/src/com/arsdigita/ui/UIResources_de.properties @@ -5,17 +5,26 @@ 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.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.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.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 diff --git a/ccm-core/src/com/arsdigita/ui/UIResources_en.properties b/ccm-core/src/com/arsdigita/ui/UIResources_en.properties index ff63cc0cf..464d988f3 100755 --- a/ccm-core/src/com/arsdigita/ui/UIResources_en.properties +++ b/ccm-core/src/com/arsdigita/ui/UIResources_en.properties @@ -19,3 +19,12 @@ 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= diff --git a/ccm-core/src/com/arsdigita/ui/UIResources_fr.properties b/ccm-core/src/com/arsdigita/ui/UIResources_fr.properties index 692322fae..4f5b28d07 100755 --- a/ccm-core/src/com/arsdigita/ui/UIResources_fr.properties +++ b/ccm-core/src/com/arsdigita/ui/UIResources_fr.properties @@ -1,4 +1,4 @@ -ui.admin.access_denied=Accès refusé +ui.admin.access_denied=Acc\u00e8s refus\u00e9 ui.admin.help=Aide ui.admin.signout=se deconnecter ui.admin.portal=Ma Porte @@ -14,4 +14,13 @@ 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ès au plan du site +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= diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties index 8ef1a8e31..7c8d5dbb6 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources.properties @@ -90,3 +90,40 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Confirm password: ui.admin.user.userpasswordform.passwordlabel=Password: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Change +ui.admin.tab.applications.title=Applications +ui.admin.applications.tree.heading=Applications +ui.admin.applications.url.validation.not_blank=The URL of an application instance can is mandatory. +ui.admin.applications.url.valiation.minmaxlength=The length of an URL of an application instance must be between 1 and 100 characters. +ui.admin.applications.title.validation.not_blank=Title is mandatory for an application instance. +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 +ui.admin.applications.desc.valiation.minmaxlength=The maximum length of a descrption of an application instance are 4000 characters. +ui.admin.applications.url.label=URL +ui.admin.applications.title.label=Title +ui.admin.applications.desc.label=Description +ui.admin.applications.url.validation.url_already_in_use=The provided URL is already in use +ui.admin.applications.url.validation.no_slash_allowed=The URL fragement may not contain slashes +ui.admin.applications.ApplicationInstancePane.title.label=Title of the instance +ui.admin.applications.ApplicationInstancePane.parent_app.label=Parent application +ui.admin.applications.ApplicationInstancePane.path.label=Path of the application +ui.admin.applications.ApplicationInstancePane.desc.label=Description +ui.admin.applications.ApplicationInstancePane.info.heading=Instance data +ui.admin.MultiInstanceApplicationPane.manage.heading=Edit instance specific settings +ui.admin.MultiInstancePane.manage.no_instance_admin_pane_found=No instance admin pane for instances of the application type '{0]' found. Maybe it is not implemented yet. +ui.admin.applications.ApplicationInfoSection.title.label=Title +ui.admin.applications.ApplicationInfoSection.app_class.label=Application Class +ui.admin.applications.ApplicationInfoSection.singleton.label=Singleton +ui.admin.applications.ApplicationInfoSection.singleton.yes=Yes +ui.admin.applications.ApplicationInfoSection.singleton.no=No +ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label=Path of the singleton instance +ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found=No instance found +ui.admin.applications.ApplicationInfoSection.heading=Application information +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header=Title +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header=Path +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header=Description +ui.admin.MultiInstanceApplicationPane.instances=Instances +ui.admin.MultiInstanceApplicationPane.manage_instances.heading=Manage instances +ui.admin.MultiInstancePane.manage.no_create_form_found=No form for manageing instances of type '{0}' found. +ui.admin.MultiInstanceApplicationPane.create_instance=Create new instance +ui.admin.SingletonApplicationPane.manage.heading=Edit settings +ui.admin.SingletonApplicationPane.manage.no_admin_pane_found=No admin pane for applications of type '{0}' found. +ui.admin.applications.ApplicationInfoSection.desc.label=Description diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties index ffce9dcce..6fb96295a 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_de.properties @@ -4,14 +4,14 @@ ui.admin.dispatcher.groupsLabel=Gruppen ui.admin.dispatcher.title=Administration ui.admin.dispatcher.usersLabel=Benutzer ui.admin.groups.actioncontinue=Fortsetzen -ui.admin.groups.groupdeletefailed=Gruppe nicht zu l\u00F6schbar +ui.admin.groups.groupdeletefailed=Gruppe nicht zu l\u00f6schbar ui.admin.groups.add=Neue Untergruppe erstellen ui.admin.groups.addeditform.namelabel=Name: -ui.admin.groups.addeditform.primaryemaillabel=Prim\u00E4re E-Mail\: +ui.admin.groups.addeditform.primaryemaillabel=Prim\u00e4re E-Mail\: ui.admin.groups.addeditform.submit=Sichern -ui.admin.groups.addgrouplabel=Neue Gruppe hinzuf\u00FCgen -ui.admin.groups.addsubmemberlabel=Mitglied hinzuf\u00FCgen -ui.admin.groups.delete=Gruppe l\u00F6schen +ui.admin.groups.addgrouplabel=Neue Gruppe hinzuf\u00fcgen +ui.admin.groups.addsubmemberlabel=Mitglied hinzuf\u00fcgen +ui.admin.groups.delete=Gruppe l\u00f6schen ui.admin.groups.deletefailed=Fehlermeldung ui.admin.groups.edit=Edit ui.admin.groups.groupedit=Edit Group @@ -27,22 +27,22 @@ ui.admin.groups.removeExisting=Als Subgruppe entfernen ui.admin.groups.search=Search for groups to add as subgroups ui.admin.groups.button.search=Suche ui.admin.groups.searchForm.noResults=Your search matches no valid groups (groups that cause circular references are excluded). Search again -ui.admin.groups.found.title=Gruppen ausw\u00E4hlen -ui.admin.groups.select.explanation=Gruppen ausw\u00E4hlen\: +ui.admin.groups.found.title=Gruppen ausw\u00e4hlen +ui.admin.groups.select.explanation=Gruppen ausw\u00e4hlen\: ui.admin.save=Sichern ui.admin.nav.logout=Abmelden ui.admin.nav.workspace=Workspace ui.admin.searchAndList.submit=Suchen ui.admin.searchAndList.submitAgain=Erneut suchen ui.admin.tab.group.title=Gruppen -ui.admin.tab.user.browse=Bl\u00E4ttern +ui.admin.tab.user.browse=Bl\u00e4ttern ui.admin.tab.user.createuser=Neuen Benutzer erstellen ui.admin.tab.user.navbartitle=Benutzerverwaltung ui.admin.tab.user.search=Suche ui.admin.tab.user.summary=Zusammenfassung ui.admin.tab.user.title=Benutzer ui.admin.user.action.continue=Fortfahren -ui.admin.user.action.delete.failed.header=Benutzer kann nicht gel\u00F6scht werden +ui.admin.user.action.delete.failed.header=Benutzer kann nicht gel\u00f6scht werden ui.admin.user.action.header=Aktionen ui.admin.user.addeditform.additionalemail=Weitere E-Mail Adresse\: ui.admin.user.addeditform.additionalemaillist=Weitere E-Mail @@ -51,7 +51,7 @@ ui.admin.user.addeditform.confirmation=Password Confirmation: ui.admin.user.addeditform.deleteemail=Entfernen ui.admin.user.addeditform.error.answer.null=This parameter is required. ui.admin.user.addeditform.error.answer.whitespace=Answer must be empty or contain non-whitespace characters -ui.admin.user.addeditform.error.password.notmatch=Passworte stimmen nicht \u00FCberein +ui.admin.user.addeditform.error.password.notmatch=Passworte stimmen nicht \u00fcberein ui.admin.user.addeditform.error.primaryemail.notunique=Primary email is not unique ui.admin.user.addeditform.error.screenname.notunique=Benutzername ist nicht eindeutig ui.admin.user.addeditform.firstname=Vorname\: @@ -74,8 +74,8 @@ ui.admin.user.ban.confirm=Are you sure you want to ban this user? ui.admin.user.unban.confirm=Are you sure you want to unban this user? ui.admin.user.ban.label=Ban user ui.admin.user.unban.label=Unban user -ui.admin.user.delete.failed.label=L\u00F6schen des Benutzers fehlgeschlagen -ui.admin.user.delete.label=Benutzer l\u00F6schen +ui.admin.user.delete.failed.label=L\u00f6schen des Benutzers fehlgeschlagen +ui.admin.user.delete.label=Benutzer l\u00f6schen ui.admin.user.editlink=Editieren ui.admin.user.groupmembership.header=Group Membership ui.admin.user.password.header=Update Security Information @@ -86,7 +86,44 @@ ui.admin.user.summarypanel.totalusers=Total users: ui.admin.user.useredit.header=Edit User Information ui.admin.user.userinfo.header=Benutzerinformation ui.admin.user.userpasswordform.answer=Antwort\:
(Leerlassen um aktuelle Antwort beizubehalten) -ui.admin.user.userpasswordform.confirmpasswordlabel=Passwort best\u00E4tigen\: +ui.admin.user.userpasswordform.confirmpasswordlabel=Passwort best\u00e4tigen\: ui.admin.user.userpasswordform.passwordlabel=Passwort\: ui.admin.user.userpasswordform.question=Frage\: -ui.admin.user.userpasswordform.submit=\u00C4ndern +ui.admin.user.userpasswordform.submit=\u00c4ndern +ui.admin.tab.applications.title=Applikationen +ui.admin.applications.tree.heading=Applikationen +ui.admin.applications.url.validation.not_blank=Die Angabe einer URL ist erforderlich +ui.admin.applications.url.valiation.minmaxlength=Die URL einer Applikations-Instanz muss zwischen einem und 100 Zeichen lang sein +ui.admin.applications.title.validation.not_blank=Der Titel ist f\u00fcr das Anlegen einer Applikations-Instanz erforderlich +ui.admin.applications.title.valiation.minmaxlength=Der Titel einer Applikations-Instanz muss zwischen einem und 200 Zeichen lang sein. +ui.admin.applications.desc.valiation.minmaxlength=Die Beschreibung einer Applikations-Instanz darf max. 4000 Zeichen lang sein +ui.admin.applications.url.label=URL +ui.admin.applications.title.label=Bezeichnung +ui.admin.applications.desc.label=Beschreibung +ui.admin.applications.url.validation.url_already_in_use=Der angegebene URL wird bereits verwendet +ui.admin.applications.url.validation.no_slash_allowed=Das URL-Fragment darf keine Schr\u00e4gstriche enthalten +ui.admin.applications.ApplicationInstancePane.title.label=Titel der Instanz +ui.admin.applications.ApplicationInstancePane.parent_app.label=\u00dcbergeordnete Applikation +ui.admin.applications.ApplicationInstancePane.path.label=Pfad der Applikation +ui.admin.applications.ApplicationInstancePane.desc.label=Beschreibung +ui.admin.applications.ApplicationInstancePane.info.heading=Daten der Instanz +ui.admin.MultiInstanceApplicationPane.manage.heading=Einstellungen der Instanz bearbeiten +ui.admin.MultiInstancePane.manage.no_instance_admin_pane_found=Kein Administrationsformular f\u00fcr Instanzen des Applikationstyps '{0}' gefunden. M\u00f6glicherweise noch nicht implementiert. +ui.admin.applications.ApplicationInfoSection.title.label=Titel +ui.admin.applications.ApplicationInfoSection.app_class.label=Applikationsklasse +ui.admin.applications.ApplicationInfoSection.singleton.label=Singleton +ui.admin.applications.ApplicationInfoSection.singleton.yes=Ja +ui.admin.applications.ApplicationInfoSection.singleton.no=Nein +ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label=Pfad der Singleton Instanz +ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found=Keine Instanz gefunden +ui.admin.applications.ApplicationInfoSection.heading=Applikationsinformationen +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header=Titel +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header=Pfad +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header=Beschreibung +ui.admin.MultiInstanceApplicationPane.instances=Instanzen +ui.admin.MultiInstanceApplicationPane.manage_instances.heading=Instanzen verwalten +ui.admin.MultiInstancePane.manage.no_create_form_found=Keine Formular zum verwalten von Applikationen des Types '{0}' gefunden. +ui.admin.MultiInstanceApplicationPane.create_instance=Neue instanz anlegen +ui.admin.SingletonApplicationPane.manage.heading=Eigenschaften bearbeiten +ui.admin.SingletonApplicationPane.manage.no_admin_pane_found=Keine Admin-Formular f\u00fcr Applikationen des Types '{0}' gefunden +ui.admin.applications.ApplicationInfoSection.desc.label=Beschreibung diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties index 8ef1a8e31..1276d793d 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_en.properties @@ -90,3 +90,40 @@ ui.admin.user.userpasswordform.confirmpasswordlabel=Confirm password: ui.admin.user.userpasswordform.passwordlabel=Password: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Change +ui.admin.tab.applications.title=Applications +ui.admin.applications.tree.heading=Applications +ui.admin.applications.url.validation.not_blank= +ui.admin.applications.url.valiation.minmaxlength= +ui.admin.applications.title.validation.not_blank= +ui.admin.applications.title.valiation.minmaxlength= +ui.admin.applications.desc.valiation.minmaxlength= +ui.admin.applications.url.label= +ui.admin.applications.title.label= +ui.admin.applications.desc.label= +ui.admin.applications.url.validation.url_already_in_use= +ui.admin.applications.url.validation.no_slash_allowed= +ui.admin.applications.ApplicationInstancePane.title.label= +ui.admin.applications.ApplicationInstancePane.parent_app.label= +ui.admin.applications.ApplicationInstancePane.path.label= +ui.admin.applications.ApplicationInstancePane.desc.label= +ui.admin.applications.ApplicationInstancePane.info.heading= +ui.admin.MultiInstanceApplicationPane.manage.heading= +ui.admin.MultiInstancePane.manage.no_instance_admin_pane_found= +ui.admin.applications.ApplicationInfoSection.title.label= +ui.admin.applications.ApplicationInfoSection.app_class.label= +ui.admin.applications.ApplicationInfoSection.singleton.label= +ui.admin.applications.ApplicationInfoSection.singleton.yes= +ui.admin.applications.ApplicationInfoSection.singleton.no= +ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label= +ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found= +ui.admin.applications.ApplicationInfoSection.heading= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header= +ui.admin.MultiInstanceApplicationPane.instances= +ui.admin.MultiInstanceApplicationPane.manage_instances.heading= +ui.admin.MultiInstancePane.manage.no_create_form_found= +ui.admin.MultiInstanceApplicationPane.create_instance= +ui.admin.SingletonApplicationPane.manage.heading= +ui.admin.SingletonApplicationPane.manage.no_admin_pane_found= +ui.admin.applications.ApplicationInfoSection.desc.label= diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties index 0a8782e27..10da70198 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -1,4 +1,4 @@ -ui.admin.dispatcher.accessDenied=Accès refusé +ui.admin.dispatcher.accessDenied=Acc\u00e8s refus\u00e9 ui.admin.dispatcher.contextTitle=Index ui.admin.dispatcher.groupsLabel=Groupes ui.admin.dispatcher.title=Administration @@ -21,31 +21,31 @@ ui.admin.groups.removesubmemberlabel=Retirer ui.admin.groups.subgroupcountlabel=Sous-groupes: ui.admin.groups.subgroups=Information sur le sous-groupe ui.admin.groups.submembers=Information sur le membre -ui.admin.nav.logout=Déconnexion +ui.admin.nav.logout=D\u00e9connexion ui.admin.nav.workspace=Espace de travail ui.admin.searchAndList.submit=Rechercher ui.admin.searchAndList.submitAgain=Rechercher suivant ui.admin.tab.group.title=Groupe ui.admin.tab.user.browse=Parcourir -ui.admin.tab.user.createuser=Créer un nouvel utilisateur +ui.admin.tab.user.createuser=Cr\u00e9er un nouvel utilisateur ui.admin.tab.user.navbartitle=Gestion de l'utilisateur ui.admin.tab.user.search=Rechercher -ui.admin.tab.user.summary=Table des matières +ui.admin.tab.user.summary=Table des mati\u00e8res ui.admin.tab.user.title=Utilisateurs ui.admin.user.action.continue=Continuer ui.admin.user.action.delete.failed.header=Impossible de supprimer l'utiisateur ui.admin.user.action.header=Actions ui.admin.user.addeditform.additionalemail=Adresse e-mail secondaire: ui.admin.user.addeditform.additionalemaillist=Autre e-mail -ui.admin.user.addeditform.answer=Réponse: +ui.admin.user.addeditform.answer=R\u00e9ponse: ui.admin.user.addeditform.confirmation=Confirmation du mot de passe: ui.admin.user.addeditform.deleteemail=Supprimer -ui.admin.user.addeditform.error.answer.null=Ce paramètre est obligatoire. -ui.admin.user.addeditform.error.answer.whitespace=La réponse doit être vide ou ne pas contenir d'espace -ui.admin.user.addeditform.error.password.notmatch=Les mots de passe sont différents +ui.admin.user.addeditform.error.answer.null=Ce param\u00e8tre est obligatoire. +ui.admin.user.addeditform.error.answer.whitespace=La r\u00e9ponse doit \u00eatre vide ou ne pas contenir d'espace +ui.admin.user.addeditform.error.password.notmatch=Les mots de passe sont diff\u00e9rents ui.admin.user.addeditform.error.primaryemail.notunique=L'e-mail principal n'est pas unique ui.admin.user.addeditform.error.screenname.notunique=Screen name n'est pas unique -ui.admin.user.addeditform.firstname=Prénom: +ui.admin.user.addeditform.firstname=Pr\u00e9nom: ui.admin.user.addeditform.lastname=Nom: ui.admin.user.addeditform.password=Mot de passe: ui.admin.user.addeditform.primaryemail=e-mail principal: @@ -56,23 +56,60 @@ ui.admin.user.addeditform.url=URL: ui.admin.user.browselink=Montrer tout ui.admin.user.browsepanel.becomeUser=Devenir cet utilisateur ui.admin.user.browsepanel.extremeaction=Action dangereuse -ui.admin.user.browsepanel.header=Tous les utilisateurs enregistrés -ui.admin.user.browsepanel.updatePassword=Mettre à jour le mot de passe -ui.admin.user.createpanel.header=Créer un nouvel utilisateur -ui.admin.user.delete.confirm=Etes vous sûr de vouloir supprimer cet utilisateur? -ui.admin.user.delete.failed.label=La suppression de l'utilisateur a échoué +ui.admin.user.browsepanel.header=Tous les utilisateurs enregistr\u00e9s +ui.admin.user.browsepanel.updatePassword=Mettre \u00e0 jour le mot de passe +ui.admin.user.createpanel.header=Cr\u00e9er un nouvel utilisateur +ui.admin.user.delete.confirm=Etes vous s\u00fbr de vouloir supprimer cet utilisateur? +ui.admin.user.delete.failed.label=La suppression de l'utilisateur a \u00e9chou\u00e9 ui.admin.user.delete.label=Supprimer cet utilisateur ui.admin.user.editlink=Modifier ui.admin.user.groupmembership.header=Groupe(s) d'appartenance -ui.admin.user.password.header=Mise à jour des informations de sécurité +ui.admin.user.password.header=Mise \u00e0 jour des informations de s\u00e9curit\u00e9 ui.admin.user.search.header=Rechercher -ui.admin.user.summarypanel.createUser=Créer un nouvel utilisateur -ui.admin.user.summarypanel.header=Table des matières +ui.admin.user.summarypanel.createUser=Cr\u00e9er un nouvel utilisateur +ui.admin.user.summarypanel.header=Table des mati\u00e8res ui.admin.user.summarypanel.totalusers=Total des utilisateurs: ui.admin.user.useredit.header=Modifier les informations de l'utilisateur ui.admin.user.userinfo.header=Informations de l'utilisateur -ui.admin.user.userpasswordform.answer=Réponse:
(Ne pas remplir pour conserver la réponse actuelle) +ui.admin.user.userpasswordform.answer=R\u00e9ponse:
(Ne pas remplir pour conserver la r\u00e9ponse actuelle) ui.admin.user.userpasswordform.confirmpasswordlabel=Confirmer le mot de passe: ui.admin.user.userpasswordform.passwordlabel=Mot de passe: ui.admin.user.userpasswordform.question=Question: ui.admin.user.userpasswordform.submit=Changer +ui.admin.tab.applications.title= +ui.admin.applications.tree.heading= +ui.admin.applications.url.validation.not_blank= +ui.admin.applications.url.valiation.minmaxlength= +ui.admin.applications.title.validation.not_blank= +ui.admin.applications.title.valiation.minmaxlength= +ui.admin.applications.desc.valiation.minmaxlength= +ui.admin.applications.url.label= +ui.admin.applications.title.label= +ui.admin.applications.desc.label= +ui.admin.applications.url.validation.url_already_in_use= +ui.admin.applications.url.validation.no_slash_allowed= +ui.admin.applications.ApplicationInstancePane.title.label= +ui.admin.applications.ApplicationInstancePane.parent_app.label= +ui.admin.applications.ApplicationInstancePane.path.label= +ui.admin.applications.ApplicationInstancePane.desc.label= +ui.admin.applications.ApplicationInstancePane.info.heading= +ui.admin.MultiInstanceApplicationPane.manage.heading= +ui.admin.MultiInstancePane.manage.no_instance_admin_pane_found= +ui.admin.applications.ApplicationInfoSection.title.label= +ui.admin.applications.ApplicationInfoSection.app_class.label= +ui.admin.applications.ApplicationInfoSection.singleton.label= +ui.admin.applications.ApplicationInfoSection.singleton.yes= +ui.admin.applications.ApplicationInfoSection.singleton.no= +ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label= +ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found= +ui.admin.applications.ApplicationInfoSection.heading= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header= +ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header= +ui.admin.MultiInstanceApplicationPane.instances= +ui.admin.MultiInstanceApplicationPane.manage_instances.heading= +ui.admin.MultiInstancePane.manage.no_create_form_found= +ui.admin.MultiInstanceApplicationPane.create_instance= +ui.admin.SingletonApplicationPane.manage.heading= +ui.admin.SingletonApplicationPane.manage.no_admin_pane_found= +ui.admin.applications.ApplicationInfoSection.desc.label= diff --git a/ccm-core/src/com/arsdigita/ui/admin/AdminServlet.java b/ccm-core/src/com/arsdigita/ui/admin/AdminServlet.java index d38092604..cb99f84bf 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/AdminServlet.java +++ b/ccm-core/src/com/arsdigita/ui/admin/AdminServlet.java @@ -18,6 +18,7 @@ */ package com.arsdigita.ui.admin; +import com.arsdigita.ui.admin.ApplicationsAdministrationTab; import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageFactory; import com.arsdigita.bebop.TabbedPane; @@ -194,11 +195,11 @@ public class AdminServlet extends BaseApplicationServlet /* * Create application administration panel */ - ApplicationsAdministrationTab appsAdministrationTab = - new ApplicationsAdministrationTab(); - + ApplicationsAdministrationTab appsAdministrationTab = + new ApplicationsAdministrationTab(); + SettingsTab settingsTab = new SettingsTab(); - + // Create the Admin's page tab bar, currently 2 elements: user & groups TabbedPane tb = new TabbedPane(); @@ -218,4 +219,5 @@ public class AdminServlet extends BaseApplicationServlet return p; } + } diff --git a/ccm-core/src/com/arsdigita/ui/admin/ApplicationsAdministrationTab.java b/ccm-core/src/com/arsdigita/ui/admin/ApplicationsAdministrationTab.java index 107ed8394..c2ac68d70 100644 --- a/ccm-core/src/com/arsdigita/ui/admin/ApplicationsAdministrationTab.java +++ b/ccm-core/src/com/arsdigita/ui/admin/ApplicationsAdministrationTab.java @@ -1,6 +1,20 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ package com.arsdigita.ui.admin; @@ -8,9 +22,11 @@ import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Link; +import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.SplitPanel; +import com.arsdigita.bebop.SimpleContainer; import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.Tree; import com.arsdigita.bebop.event.ChangeEvent; import com.arsdigita.bebop.event.ChangeListener; import com.arsdigita.bebop.event.TableActionEvent; @@ -20,53 +36,251 @@ import com.arsdigita.bebop.table.TableColumn; import com.arsdigita.bebop.table.TableColumnModel; import com.arsdigita.bebop.table.TableModel; import com.arsdigita.bebop.table.TableModelBuilder; -import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.toolbox.ui.LayoutPanel; +import com.arsdigita.toolbox.ui.Section; +import com.arsdigita.ui.admin.applications.ApplicationCreateForm; +import com.arsdigita.ui.admin.applications.ApplicationInstancePane; +import com.arsdigita.ui.admin.applications.ApplicationManager; +import com.arsdigita.ui.admin.applications.BaseApplicationPane; +import com.arsdigita.ui.admin.applications.MultiInstanceApplicationPane; +import com.arsdigita.ui.admin.applications.SingletonApplicationPane; +import com.arsdigita.ui.admin.applications.tree.ApplicationTreeModelBuilder; +import com.arsdigita.ui.admin.GlobalizationUtil; import com.arsdigita.util.LockableImpl; import com.arsdigita.web.Application; import com.arsdigita.web.ApplicationCollection; +import com.arsdigita.web.ApplicationType; +import com.arsdigita.web.ApplicationTypeCollection; +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; /** - * + * A tab for managing Application and application instances. + * * @author pb * @author Jens Pelzetter */ -public class ApplicationsAdministrationTab extends BoxPanel - implements AdminConstants, ChangeListener { +public class ApplicationsAdministrationTab extends BoxPanel implements AdminConstants, ChangeListener { - private GlobalizedMessage m_title; + //private GlobalizedMessage m_title; + private final Tree applicationTree; + private final Map singletonAppPanes = + new HashMap(); + private final Map> multiInstAppPanes = + new HashMap>(); + private final Map appPanes = new HashMap(); + private final Map instancePanes = new HashMap(); + private SimpleContainer visiblePane; + //private final Label label1; + //private final Label label2; /** * Constructor */ public ApplicationsAdministrationTab() { + super(); + // m_title = "TEST für ein neues Pannel"; setClassAttr("sidebarNavPanel"); setAttribute("navbar-title", "Sitemap"); // m_componentList = new ArrayList(); // m_keys = new ArrayList(); + applicationTree = new Tree(new ApplicationTreeModelBuilder()); + applicationTree.addChangeListener(this); - final BoxPanel box = new BoxPanel(); - box.setClassAttr("main"); + final Section treeSection = new Section(); + treeSection.setHeading(GlobalizationUtil.globalize("ui.admin.applications.tree.heading")); + treeSection.setBody(applicationTree); - final SplitPanel panel = new SplitPanel(); - panel.setClassAttr("sidebarNavPanel"); - panel.setRightComponent(box); + //final BoxPanel panel1 = new BoxPanel(); +// label1 = new Label("login"); +// label2 = new Label("ppp"); +// panel1.add(label1); +// panel1.add(label2); - box.add(new ApplicationsTable()); + + final LayoutPanel panel = new LayoutPanel(); + //panel.setLeft(applicationTree); + panel.setLeft(treeSection); + //panel.setRight(new Label("<<>>")); + //panel.setRight(panel1); + + final ApplicationTypeCollection applicationTypes = ApplicationType.retrieveAllApplicationTypes(); + + final Map> createForms = retrieveAppCreateForms(); + final Map> managementForms = retrieveAppManagers(); + + while (applicationTypes.next()) { + if (applicationTypes.getApplicationType().isSingleton()) { + createSingletonAppPane(applicationTypes.getApplicationType(), managementForms); + } else { + createAppPane(applicationTypes.getApplicationType(), createForms, managementForms); + } + } + + final BoxPanel appPanel = new BoxPanel(); + for (Map.Entry entry : appPanes.entrySet()) { + appPanel.add(entry.getValue()); + } + + for (Map.Entry entry : instancePanes.entrySet()) { + appPanel.add(entry.getValue()); + } + panel.setRight(appPanel); + + + + + +// final BoxPanel box = new BoxPanel(); +// box.setClassAttr("main"); +// +// final SplitPanel panel = new SplitPanel(); +// panel.setClassAttr("sidebarNavPanel"); +// panel.setLeftComponent(applicationTree); +// panel.setRightComponent(box); +// +// //box.add(new ApplicationsTable()); +// box.add(new Label("<<>>")); +// add(panel); } + @SuppressWarnings("rawtypes") + private Map> retrieveAppCreateForms() { + final Map> appCreateForms = new HashMap>(); + + final ServiceLoader loader = ServiceLoader.load(ApplicationCreateForm.class); + for (ApplicationCreateForm appCreateForm : loader) { + appCreateForms.put(appCreateForm.getAppClassName(), appCreateForm); + } + + return appCreateForms; + } + + @SuppressWarnings("rawtypes") + private Map> retrieveAppManagers() { + final Map> appManagers = new HashMap>(); + + final ServiceLoader loader = ServiceLoader.load(ApplicationManager.class); + for (ApplicationManager appManager : loader) { + appManagers.put(appManager.getApplication().getName(), appManager); + } + + return appManagers; + } + + private void createSingletonAppPane(final ApplicationType applicationType, + final Map> managementForms) { + final String appObjectType = applicationType.getApplicationObjectType(); + + final ApplicationManager manager = managementForms.get(appObjectType); + final SingletonApplicationPane pane; + if (manager == null) { + pane = new SingletonApplicationPane(applicationType, null); + } else { + pane = new SingletonApplicationPane( + applicationType, managementForms.get(appObjectType).getApplicationAdminForm()); + } + //singletonAppPanes.put(appObjectType, pane); + appPanes.put(appObjectType, pane); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private void createAppPane(final ApplicationType applicationType, + final Map> createForms, + final Map> managementForms) { + final MultiInstanceApplicationPane appPane = new MultiInstanceApplicationPane( + applicationType, + createForms.get(applicationType.getApplicationObjectType())); + //multiInstAppPanes.put(applicationType.getApplicationObjectType(), appPane); + appPanes.put(applicationType.getApplicationObjectType(), appPane); + + final ApplicationCollection instances = Application.retrieveAllApplications( + applicationType.getApplicationObjectType()); + + while (instances.next()) { + createInstancePane(instances.getApplication(), managementForms); + } + } + + private void createInstancePane(final Application application, + final Map> managementForms) { + final ApplicationManager manager = managementForms.get(application.getClass().getName()); + + final ApplicationInstancePane instPane; + if (manager == null) { + instPane = new ApplicationInstancePane(application, null); + } else { + instPane = new ApplicationInstancePane( + application, + managementForms.get(application.getClass().getName()).getApplicationAdminForm()); + } + instancePanes.put(application.getClass().getName(), instPane); + } + + @Override + public void register(final Page page) { + super.register(page); + + for (Map.Entry entry : appPanes.entrySet()) { + page.setVisibleDefault(entry.getValue(), false); + } + for (Map.Entry entry : instancePanes.entrySet()) { + page.setVisibleDefault(entry.getValue(), false); + } + //page.setVisibleDefault(label1, false); + //page.setVisibleDefault(label2, false); + } + /** * - * @param e + * @param event */ @Override - public void stateChanged(ChangeEvent e) { + public void stateChanged(final ChangeEvent event) { + + final PageState state = event.getPageState(); + + System.out.println("State changed."); + + final String selectedKey = (String) applicationTree.getSelectedKey(state); + if (selectedKey != null) { + if (selectedKey.contains(".")) { + // Selected key is a classname and therefore the key of an ApplicationPane + final BaseApplicationPane pane = appPanes.get(selectedKey); + if (pane != null) { + setPaneVisible(pane, state); + } + } else { + // Selected key is the name of a instance pane + final ApplicationInstancePane pane = instancePanes.get(selectedKey); + if (pane != null) { + setPaneVisible(pane, state); + } + } + } + + //ToDo Find out if the key is the key of a application type (contains dots) or the key of an instance (may + //contains Slashes + + +// if ("ui.login.Login".equals(applicationTree.getSelectedKey(state))) { +// label1.setVisible(state, true); +// label2.setVisible(state, false); +// } else if ("com.arsdigita.cms.publicpersonalprofile.PublicPersonalProfile".equals(applicationTree. +// getSelectedKey(state))) { +// label1.setVisible(state, false); +// label2.setVisible(state, true); +// } else { +// label1.setVisible(state, false); +// label2.setVisible(state, false); +// } - PageState ps = e.getPageState(); // String key = (String) m_tree.getSelectedKey(ps); // added cg - reset existing group add panel to the search screen // when a new group is selected from the tree @@ -75,6 +289,15 @@ public class ApplicationsAdministrationTab extends BoxPanel // setTab(selectedIndex, ps); } + private void setPaneVisible(final SimpleContainer pane, final PageState state) { + if (visiblePane != null) { + visiblePane.setVisible(state, false); + } + + pane.setVisible(state, true); + visiblePane = pane; + } + private class ApplicationsTable extends Table implements TableActionListener { private static final String COL_APP_CLASS = "col_app_class"; @@ -100,7 +323,7 @@ public class ApplicationsAdministrationTab extends BoxPanel colModel.add(new TableColumn( 2, "App View URL", - COL_APP_VIEW_URL)); + COL_APP_VIEW_URL)); colModel.add(new TableColumn( 3, "Is Singleton?", @@ -145,7 +368,7 @@ public class ApplicationsAdministrationTab extends BoxPanel final Object key, final int row, final int column) { - return new Link(value.toString(), value.toString()); + return new Link(value.toString(), value.toString()); } }); @@ -219,7 +442,7 @@ public class ApplicationsAdministrationTab extends BoxPanel case 1: return app.getApplicationType().getTitle(); case 2: - return app.getPath(); + return app.getPath(); case 3: return Boolean.toString(app.getApplicationType().isSingleton()); default: @@ -239,7 +462,7 @@ public class ApplicationsAdministrationTab extends BoxPanel return String.format("%s/%s", constructAppPath(app.getParentApplication()), app.getPath()); } } - + } @Override diff --git a/ccm-core/src/com/arsdigita/ui/admin/GlobalizationUtil.java b/ccm-core/src/com/arsdigita/ui/admin/GlobalizationUtil.java new file mode 100644 index 000000000..0641f5c4a --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/GlobalizationUtil.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.globalization.GlobalizedMessage; + +/** + * Globalization Util for admin classes + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class GlobalizationUtil { + + private static final String BUNDLE_NAME = "com.arsdigita.ui.admin.AdminResources"; + + public static GlobalizedMessage globalize(final String key) { + return new GlobalizedMessage(key, BUNDLE_NAME); + } + + public static GlobalizedMessage globalize(final String key, final Object[] args) { + return new GlobalizedMessage(key, BUNDLE_NAME, args); + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/GroupAdministrationTab.java b/ccm-core/src/com/arsdigita/ui/admin/GroupAdministrationTab.java index 632a998da..e1fdcebec 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/GroupAdministrationTab.java +++ b/ccm-core/src/com/arsdigita/ui/admin/GroupAdministrationTab.java @@ -156,7 +156,8 @@ class GroupAdministrationTab extends BoxPanel BoxPanel c = new BoxPanel(); c.setClassAttr("navbar"); - m_tree = new Tree(new GroupTreeModel()); + //m_tree = new Tree(new GroupTreeModel()); + m_tree = new Tree(new GroupTreeModelBuilder()); m_tree.addChangeListener(this); c.add(m_tree); diff --git a/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModel.java b/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModel.java index 9c08ca604..062b96117 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModel.java +++ b/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModel.java @@ -66,6 +66,7 @@ public class GroupTreeModel implements TreeModel { public void remove() { throw new UnsupportedOperationException(); } + } /** @@ -113,22 +114,22 @@ public class GroupTreeModel implements TreeModel { DataCollection coll = ssn.retrieve("com.arsdigita.kernel.Group"); coll.addInSubqueryFilter("id", "com.arsdigita.ui.admin.AllNoParentGroups"); - - coll.addOrder("lower("+ Group.DISPLAY_NAME + ") asc"); - + + coll.addOrder("lower(" + Group.DISPLAY_NAME + ") asc"); + return new GroupIterator(new ACSObjectCollection(coll)); } else { Group group = null; try { - group = new Group(new BigDecimal((String)n.getKey())); + group = new Group(new BigDecimal((String) n.getKey())); } catch (DataObjectNotFoundException ed) { // Group is not found just return null. return null; } GroupCollection coll = group.getSubgroups(); - coll.addOrder("lower("+ Group.DISPLAY_NAME + ") asc"); + coll.addOrder("lower(" + Group.DISPLAY_NAME + ") asc"); return new GroupIterator(coll); @@ -147,6 +148,7 @@ class RootTreeNode implements TreeNode { public Object getElement() { return "/"; } + } class GroupTreeNode implements TreeNode { @@ -166,4 +168,5 @@ class GroupTreeNode implements TreeNode { public Object getElement() { return m_name; } + } diff --git a/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModelBuilder.java b/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModelBuilder.java new file mode 100644 index 000000000..f35773434 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/GroupTreeModelBuilder.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Tree; +import com.arsdigita.bebop.tree.TreeModel; +import com.arsdigita.bebop.tree.TreeModelBuilder; +import com.arsdigita.util.LockableImpl; + +/** + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class GroupTreeModelBuilder extends LockableImpl implements TreeModelBuilder { + + public TreeModel makeModel(final Tree tree, final PageState state) { + tree.expand("-1", state); + return new GroupTreeModel(); + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/SettingsTab.java b/ccm-core/src/com/arsdigita/ui/admin/SettingsTab.java deleted file mode 100644 index 9b4eb530b..000000000 --- a/ccm-core/src/com/arsdigita/ui/admin/SettingsTab.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.arsdigita.ui.admin; - -import com.arsdigita.bebop.BoxPanel; -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Table; -import com.arsdigita.bebop.event.TableActionEvent; -import com.arsdigita.bebop.event.TableActionListener; -import com.arsdigita.bebop.table.TableModel; -import com.arsdigita.bebop.table.TableModelBuilder; -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.packaging.Config; -import com.arsdigita.runtime.ConfigRegistry; -import com.arsdigita.util.LockableImpl; -import com.arsdigita.util.parameter.ErrorList; -import com.arsdigita.util.parameter.Parameter; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.List; - -/** - * Tab for viewing and changing the settings in the registry. - * - * @author Jens Pelzetter - */ -public class SettingsTab extends BoxPanel implements AdminConstants { - - private GlobalizedMessage title; - - public SettingsTab() { - - setClassAttr("sidebarNavPanel"); - setAttribute("navbar-title", "Settings"); - - final BoxPanel box = new BoxPanel(BoxPanel.VERTICAL); - box.setClassAttr("main"); - - final ConfigRegistry registry = new ConfigRegistry(); - final Config config = new Config(registry); - final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - final PrintStream printStream = new PrintStream(outputStream); - config.load(printStream); - final String errors = outputStream.toString(); - - box.add(new Label(errors)); - - final List contexts = registry.getContexts(); - for (Object context : contexts) { - final String storage = registry.getStorage((Class) context); - add(new Label(String.format("%s", ((Class) context).getName()), false)); - } - - final List parameters = config.getParameters(); - for(int i = 0; i < parameters.size(); i++) { - final Parameter parameter = (Parameter) parameters.get(i); - add(new Label(parameter.getName())); - } - - add(box); - - } - - private class SettingsTable extends Table implements TableActionListener { - - public SettingsTable() { - super(); - - setEmptyView(new Label("No settings found")); - - //Add columns here - - setModelBuilder(new SettingsTableModelBuilder()); - } - - public void cellSelected(TableActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - public void headSelected(TableActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } - - private class SettingsTableModelBuilder extends LockableImpl implements TableModelBuilder { - - @Override - public TableModel makeModel(final Table table, final PageState state) { - return new SettingsTableModel(table); - } - } - - private class SettingsTableModel implements TableModel { - - private final Table table; - private final String errors; - private final ConfigRegistry registry; - private final Config config; - - public SettingsTableModel(final Table table) { - this.table = table; - - registry = new ConfigRegistry(); - config = new Config(registry); - final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - final PrintStream printStream = new PrintStream(outputStream); - config.load(printStream); - errors = outputStream.toString(); - - - - } - - @Override - public int getColumnCount() { - return table.getColumnModel().size(); - } - - public boolean nextRow() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - public Object getElementAt(int columnIndex) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - public Object getKeyAt(int columnIndex) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } -} diff --git a/ccm-core/src/com/arsdigita/ui/admin/UserBrowsePane.java b/ccm-core/src/com/arsdigita/ui/admin/UserBrowsePane.java index e3bc80d51..2fe054ef0 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/UserBrowsePane.java +++ b/ccm-core/src/com/arsdigita/ui/admin/UserBrowsePane.java @@ -20,6 +20,7 @@ package com.arsdigita.ui.admin; +import com.arsdigita.ui.admin.ApplicationsAdministrationTab; import com.arsdigita.bebop.ActionLink; import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.Component; diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractApplicationManager.java b/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractApplicationManager.java new file mode 100644 index 000000000..403cf89b2 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractApplicationManager.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Form; +import com.arsdigita.web.Application; + +/** + * Provides a basic implementation of {@link ApplicationManager} for multi-instance applications. + * + * @param Type of the application for which this ApplicationManager provides the administration forms. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public abstract class AbstractApplicationManager implements ApplicationManager{ + + /** + * Provides a standard form for creating new instances of an application. + * Suitable for most application types. + * + * @param appClass + * @return The standard form for creating new instances of an application. + */ + public Form getApplicationCreateForm(final Class appClass) { + return new ApplicationCreateForm(appClass); + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractSingletonApplicationManager.java b/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractSingletonApplicationManager.java new file mode 100644 index 000000000..9ab9c6c8b --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/AbstractSingletonApplicationManager.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Form; +import com.arsdigita.web.Application; + +/** + * An abstract class providing a default implementation of {@link ApplicationManager#getApplicationCreateForm()}. + * + * @param Type of the application for which this ApplicationManager provides the administration forms. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public abstract class AbstractSingletonApplicationManager implements ApplicationManager{ + + /** + * Implementation of {@link ApplicationManager#getApplicationCreateForm()} + * for singleton applications. + * + * @return {@code} null because it is not possible to create instances + * of singleton applications. + */ + @SuppressWarnings("PMD.EmptyMethodInAbstractClassShouldBeAbstract") + public final Form getApplicationCreateForm() { + return null; + } +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationCreateForm.java b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationCreateForm.java new file mode 100644 index 000000000..44074d270 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationCreateForm.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.FormValidationListener; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.StringInRangeValidationListener; +import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.domain.DomainObjectFactory; +import com.arsdigita.persistence.DataCollection; +import com.arsdigita.persistence.Session; +import com.arsdigita.persistence.SessionManager; +import com.arsdigita.ui.admin.GlobalizationUtil; +import com.arsdigita.web.Application; +import com.arsdigita.web.ApplicationType; + +/** + * Basic form for creating new Application instances. Should be suitable for + * most applications types. If you have special needs... $todo + * + * This form does not support parent/child application structures. If + * your app needs this, add a widget for selecting the parent application + * and extend the process method. + * + * @param Type of application + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class ApplicationCreateForm + extends Form + implements FormProcessListener, FormValidationListener { + + public static final String FORM_NAME = "ApplicationCreateForm"; + private static final String APPLICATION_URL = "applicationUrl"; + private static final String APPLICATION_TITLE = "applicationTitle"; + private static final String APPLICATION_DESC = "applicationDesc"; + private final String appClassName; + private final ApplicationType applicationType; + private final TextField applicationUrl; + private final TextField applicationTitle; + private final TextArea applicationDesc; + + public ApplicationCreateForm(final Class appClass) { + + super(FORM_NAME); + + appClassName = appClass.getName(); + + final Session session = SessionManager.getSession(); + final DataCollection appTypes = session.retrieve(ApplicationType.BASE_DATA_OBJECT_TYPE); + appTypes.addEqualsFilter("objectType", appClass.getName()); + + if (appTypes.isEmpty()) { + throw new IllegalArgumentException(String.format("Not application found for object type '%s'.", + appClass.getName())); + } + + appTypes.next(); + applicationType = (ApplicationType) DomainObjectFactory.newInstance(appTypes.getDataObject()); + + applicationUrl = new TextField(new StringParameter(APPLICATION_URL)); + applicationUrl.setSize(42); + applicationUrl.addValidationListener(new NotNullValidationListener( + GlobalizationUtil.globalize("ui.admin.applications.url.validation.not_blank"))); + applicationUrl.addValidationListener(new StringInRangeValidationListener(1, 100, GlobalizationUtil.globalize( + "ui.admin.applications.url.valiation.minmaxlength"))); + + applicationTitle = new TextField(new StringParameter(APPLICATION_TITLE)); + applicationTitle.setSize(42); + applicationTitle.addValidationListener(new NotNullValidationListener( + GlobalizationUtil.globalize("ui.admin.applications.title.validation.not_blank"))); + applicationTitle.addValidationListener(new StringInRangeValidationListener(1, 200, GlobalizationUtil.globalize( + "ui.admin.applications.title.valiation.minmaxlength"))); + + applicationDesc = new TextArea(new StringParameter(APPLICATION_DESC)); + applicationDesc.setRows(5); + applicationDesc.setCols(42); + applicationDesc.addValidationListener(new StringInRangeValidationListener(0, 4000, GlobalizationUtil.globalize( + "ui.admin.applications.desc.valiation.minmaxlength"))); + + add(new Label(GlobalizationUtil.globalize("ui.admin.applications.url.label"))); + add(applicationUrl); + add(new Label(GlobalizationUtil.globalize("ui.admin.applications.title.label"))); + add(applicationTitle); + add(new Label(GlobalizationUtil.globalize("ui.admin.applications.desc.label"))); + add(applicationDesc); + + + } + + /** + * Creates a new application instance using the provided data. + * + * @param event + * @throws FormProcessException + */ + public void process(final FormSectionEvent event) throws FormProcessException { + final PageState state = event.getPageState(); + + final Application application = Application.createApplication(applicationType, + (String)applicationUrl.getValue(state), + (String)applicationTitle.getValue(state), + null, + false); + application.setDescription((String) applicationDesc.getValue(state)); + } + + public void validate(final FormSectionEvent event) throws FormProcessException { + final PageState state = event.getPageState(); + + final String url = (String) applicationUrl.getValue(state); + + if (url.contains("/")) { + throw new FormProcessException((String) GlobalizationUtil.globalize( + "ui.admin.applications.url.validation.no_slash_allowed").localize()); + } + + if (Application.isInstalled(Application.BASE_DATA_OBJECT_TYPE, url)) { + throw new FormProcessException((String) GlobalizationUtil.globalize( + "ui.admin.applications.url.validation.url_already_in_use").localize()); + } + } + + public String getAppClassName() { + return appClassName; + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationInstancePane.java b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationInstancePane.java new file mode 100644 index 000000000..ef7e69ca4 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationInstancePane.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.SegmentedPanel; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.ui.admin.GlobalizationUtil; + +import com.arsdigita.web.Application; + +/** + * This pane shows informations about a specific instance of a multi instance application, like title, parent + * application (if any) and the path. Also it contains a form for editing settings specific to the instance. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class ApplicationInstancePane extends SegmentedPanel { + + public ApplicationInstancePane(final Application appInstance, final SimpleContainer appAdminPane) { + + super(); + + final InfoPanel appInstInfoPanel = new InfoPanel(); + appInstInfoPanel.addLine("ui.admin.applications.ApplicationInstancePane.title.label", + appInstance.getTitle()); + if (appInstance.getParentApplication() != null) { + appInstInfoPanel.addLine("ui.admin.applications.ApplicationInstancePane.parent_app.label", + appInstance.getParentApplication().getPath()); + } + appInstInfoPanel.addLine("ui.admin.applications.ApplicationInstancePane.path.label", + appInstance.getPath()); + appInstInfoPanel.addLine("ui.admin.applications.ApplicationInstancePane.desc.label", + appInstance.getDescription()); + + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.applications.ApplicationInstancePane.info.heading")), + appInstInfoPanel); + + if (appAdminPane == null) { + addSegment(new Label(com.arsdigita.ui.util.GlobalizationUtil.globalize( + "ui.admin.MultiInstanceApplicationPane.manage.heading")), + new Label(com.arsdigita.ui.util.GlobalizationUtil.globalize( + "ui.admin.MultiInstancePane.manage.no_instance_admin_pane_found", + new String[]{appInstance.getApplicationType().getApplicationObjectType()}))); + } else { + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.applications.ApplicationInstancePane.manage.heading")), + appAdminPane); + } + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationManager.java b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationManager.java new file mode 100644 index 000000000..6133b5a38 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/ApplicationManager.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.web.Application; +import java.util.ServiceLoader; + +/** + * Implementations of this class are used by the new + * {@link ApplicationsAdministrationTab} to get the forms for editing the + * configuration of an application and for creating new instances of an + * application. + * + * The {@link ApplicationsAdministrationTab} uses the {@link ServiceLoader} + * from the Java Standard Library to find all implementations of this interface. + * To make implementations of this interface known add an file named + * {@code com.arsdigita.ui.admin.applications.ApplicationManager} to the + * {@code META-INF/services} directory of the module which provides the + * application. In this file add a line with the full qualified class name + * of each implementations of this interface provided by the module. + * + * There a two abstract classes to help you with implementing this class. + * {@link AbstractSingletonApplicationManager} is suitable for singleton + * applications. {@link AbstractApplicationManager} is for multi-instance + * applications. + * + * @param Type of the application for which this ApplicationManager + * provides the administration forms. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public interface ApplicationManager { + + /** + * Used to determine the Applications class for which this + * manager provides the administration forms. + * + * @return The class of the application for which this + * manager provides the administration forms. + */ + Class getApplication(); + + /** + * Provides a pane with administration forms for the application or for an + * instance of the application if the application is not a singleton. + * + * @return A container containing one or more forms for managing instances + * of an application. + */ + SimpleContainer getApplicationAdminForm(); + + /** + * Provides a form for creating new instances of applications. For + * singleton applications an implementation of this method will return + * {@code null}. + * + * @return A form for creating new instances of applications or + * {@code null} if the is a singleton. + */ + Form getApplicationCreateForm(); + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/BaseApplicationPane.java b/ccm-core/src/com/arsdigita/ui/admin/applications/BaseApplicationPane.java new file mode 100644 index 000000000..670fae476 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/BaseApplicationPane.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.SegmentedPanel; +import com.arsdigita.ui.admin.GlobalizationUtil; +import com.arsdigita.web.Application; +import com.arsdigita.web.ApplicationCollection; +import com.arsdigita.web.ApplicationType; + +/** + * Basic application pane containing the parts common for singleton and multi instance applications types. Shows + * informations about a specific application type. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class BaseApplicationPane extends SegmentedPanel { + + //private final ApplicationType applicationType; + public BaseApplicationPane(final ApplicationType applicationType) { + super(); + + //this.applicationType = applicationType; + + final InfoPanel appInfoPanel = new InfoPanel(); + appInfoPanel.addLine("ui.admin.applications.ApplicationInfoSection.title.label", + applicationType.getTitle()); + appInfoPanel.addLine("ui.admin.applications.ApplicationInfoSection.app_class.label", + applicationType.getApplicationObjectType()); + if (applicationType.isSingleton()) { + appInfoPanel.addLine("ui.admin.applications.ApplicationInfoSection.singleton.label", + "ui.admin.applications.ApplicationInfoSection.singleton.yes", + true); + } else { + appInfoPanel.addLine("ui.admin.applications.ApplicationInfoSection.singleton.label", + "ui.admin.applications.ApplicationInfoSection.singleton.no", + true); + } + appInfoPanel.addLine("ui.admin.applications.ApplicationInfoSection.desc.label", + applicationType.getDescription()); + if (applicationType.isSingleton()) { + final ApplicationCollection applications = Application.retrieveAllApplications(applicationType. + getApplicationObjectType()); + if (applications.next()) { + appInfoPanel.addLine( + "ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label", + applications.getApplication().getPath()); + } else { + appInfoPanel.addLine( + "ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label", + "ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found"); + } + applications.close(); + } + + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.applications.ApplicationInfoSection.heading")), + appInfoPanel); + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/InfoPanel.java b/ccm-core/src/com/arsdigita/ui/admin/applications/InfoPanel.java new file mode 100644 index 000000000..e32e4f983 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/InfoPanel.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.Label; +import com.arsdigita.ui.admin.GlobalizationUtil; + +/** + * A helper class for creating a column panel with two labels in each row. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class InfoPanel extends ColumnPanel { + + public InfoPanel() { + super(2); + } + + public void addLine(final String labelKey, final String data) { + addLine(labelKey, data, false); + } + + public void addLine(final String labelKey, final String data, final boolean globalizeData) { + add(new Label(GlobalizationUtil.globalize(labelKey))); + if (globalizeData) { + add(new Label(GlobalizationUtil.globalize(data))); + } else { + add(new Label(data)); + } + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/MultiInstanceApplicationPane.java b/ccm-core/src/com/arsdigita/ui/admin/applications/MultiInstanceApplicationPane.java new file mode 100644 index 000000000..d5d490869 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/MultiInstanceApplicationPane.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.bebop.table.TableModel; +import com.arsdigita.bebop.table.TableModelBuilder; +import com.arsdigita.ui.admin.GlobalizationUtil; +import com.arsdigita.util.LockableImpl; +import com.arsdigita.web.Application; +import com.arsdigita.web.ApplicationCollection; +import com.arsdigita.web.ApplicationType; + +/** + * Pane for multi instance applications. Additional to the data provided by {@link BaseApplicationPane} it shows a + * table of all instances of the application type and a form for creating new instances of the application type. + * + * @param + * @author Jens Pelzetter + * @version $Id$ + */ +public class MultiInstanceApplicationPane extends BaseApplicationPane { + + private final static int COL_TITLE = 0; + private final static int COL_URL = 1; + private final static int COL_DESC = 2; + + public MultiInstanceApplicationPane(final ApplicationType applicationType, + final ApplicationCreateForm createForm) { + super(applicationType); + + final ApplicationCollection applications = Application.retrieveAllApplications(applicationType. + getApplicationObjectType()); + final Table table = new Table(); + table.getColumnModel().add(new TableColumn(COL_TITLE, GlobalizationUtil.globalize( + "ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header"))); + table.getColumnModel().add(new TableColumn(COL_URL, GlobalizationUtil.globalize( + "ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header"))); + table.getColumnModel().add(new TableColumn(COL_DESC, GlobalizationUtil.globalize( + "ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header"))); + + table.setModelBuilder(new ApplicationInstancesTableModelBuilder(applications)); + + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.MultiInstanceApplicationPane.instances")), + table); + + if (createForm == null) { + addSegment(new Label(com.arsdigita.ui.util.GlobalizationUtil.globalize( + "ui.admin.MultiInstanceApplicationPane.manage_instances.heading")), + new Label(com.arsdigita.ui.util.GlobalizationUtil.globalize( + "ui.admin.MultiInstancePane.manage.no_create_form_found", + new String[]{applicationType.getApplicationObjectType()}))); + } else { + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.MultiInstanceApplicationPane.create_instance")), + createForm); + + } + } + + private class ApplicationInstancesTableModelBuilder extends LockableImpl implements TableModelBuilder { + + private final ApplicationCollection applications; + + public ApplicationInstancesTableModelBuilder(final ApplicationCollection applications) { + super(); + + this.applications = applications; + } + + public TableModel makeModel(final Table table, final PageState state) { + return new ApplicationInstancesTableModel(table, applications); + } + + } + + private class ApplicationInstancesTableModel implements TableModel { + + private final Table table; + private final ApplicationCollection applications; + + public ApplicationInstancesTableModel(final Table table, final ApplicationCollection applications) { + this.table = table; + this.applications = applications; + } + + public int getColumnCount() { + return table.getColumnModel().size(); + } + + public boolean nextRow() { + return applications.next(); + } + + public Object getElementAt(final int columnIndex) { + switch (columnIndex) { + case COL_TITLE: + return applications.getApplication().getTitle(); + case COL_DESC: + return applications.getApplication().getDescription(); + case COL_URL: + return applications.getApplication().getPath(); + default: + return null; + } + } + + public Object getKeyAt(final int columnIndex) { + return applications.getApplication().getPath(); + } + + } +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/SingletonApplicationPane.java b/ccm-core/src/com/arsdigita/ui/admin/applications/SingletonApplicationPane.java new file mode 100644 index 000000000..be207cec1 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/SingletonApplicationPane.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications; + +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.SimpleContainer; +import com.arsdigita.ui.admin.GlobalizationUtil; +import com.arsdigita.web.ApplicationType; + +/** + * Pane for managing singleton applications. Shows a form to edit application specific settings. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class SingletonApplicationPane extends BaseApplicationPane { + + public SingletonApplicationPane(final ApplicationType applicationType, final SimpleContainer appAdminPane) { + super(applicationType); + + if (appAdminPane == null) { + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.SingletonApplicationPane.manage.heading")), + new Label(GlobalizationUtil.globalize( + "ui.admin.SingletonApplicationPane.manage.no_admin_pane_found", + new String[]{applicationType.getApplicationObjectType()}))); + } else { + addSegment(new Label(GlobalizationUtil.globalize( + "ui.admin.SingletonApplicationPane.manage.heading")), + appAdminPane); + } + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationInstanceTreeNode.java b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationInstanceTreeNode.java new file mode 100644 index 000000000..cde45114a --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationInstanceTreeNode.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications.tree; + +import com.arsdigita.bebop.tree.TreeNode; +import com.arsdigita.ui.admin.ApplicationsAdministrationTab; +import com.arsdigita.web.Application; + +/** + * Tree Node for the application tree representing an instance of a application. + * + * @author Jens Pelzetter + * @version $Id$ + * + * @see ApplicationTreeModel + * @see ApplicationTreeModelBuilder + * @see ApplicationTypeTreeNode + * @see ApplicationsAdministrationTab + * @see TreeNode + */ +public class ApplicationInstanceTreeNode implements TreeNode { + + /** + * The application instance represented by this {@code TreeNode} + */ + private final Application application; + + /** + * Constructor + * + * @param application The application instance to represent by this {@code TreeNode} + */ + public ApplicationInstanceTreeNode(final Application application) { + this.application = application; + } + + /** + * Returns the key for this {@link TreeNode}. + * + * @return The path of the application instance. + * @see TreeNode#getKey() + */ + public Object getKey() { + return application.getPath(); + } + + /** + * Data to show in the tree for this node. + * + * @return The title of the application instance + * @see TreeNode#getElement() + */ + public Object getElement() { + return application.getTitle(); + } + +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModel.java b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModel.java new file mode 100644 index 000000000..7ad9e7035 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModel.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications.tree; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.tree.TreeModel; +import com.arsdigita.bebop.tree.TreeNode; +import com.arsdigita.ui.admin.ApplicationsAdministrationTab; +import com.arsdigita.web.Application; +import com.arsdigita.web.ApplicationCollection; +import com.arsdigita.web.ApplicationType; +import com.arsdigita.web.ApplicationTypeCollection; +import java.util.Iterator; + +/** + * A {@link TreeModel} for the tree of applications in {@link ApplicationsAdministrationTab}. The tree consists of two + * different types of nodes: Nodes for {@link ApplicationTypes} and nodes for {@link Application} instances. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class ApplicationTreeModel implements TreeModel { + + public ApplicationTreeModel() { + //Nothing + } + + public TreeNode getRoot(final PageState state) { + return new RootTreeNode(); + } + + public boolean hasChildren(final TreeNode node, final PageState state) { + if (node instanceof RootTreeNode) { + return true; + } else if (node instanceof ApplicationTypeTreeNode) { + final ApplicationTypeTreeNode typeTreeNode = (ApplicationTypeTreeNode) node; + + if (typeTreeNode.getApplicationType().isSingleton()) { + return false; + } else { + return !retrieveApplicationInstances(typeTreeNode.getApplicationType()).isEmpty(); + } + } else if (node instanceof ApplicationInstanceTreeNode) { + return false; + } else { + throw new IllegalArgumentException( + "The ApplicationTreeModel can only work with ApplicationTypeTreeNodes and" + + "ApplicationInstanceTreeNodes."); + } + } + + public Iterator getChildren(final TreeNode node, final PageState state) { + if (node instanceof RootTreeNode) { + final ApplicationTypeCollection appTypes = ApplicationType.retrieveAllApplicationTypes(); + appTypes.addOrder("title"); + + return new AppTypesIterator(appTypes); + } else if (node instanceof ApplicationTypeTreeNode) { + final ApplicationTypeTreeNode typeTreeNode = (ApplicationTypeTreeNode) node; + final ApplicationType appType = typeTreeNode.getApplicationType(); + + final ApplicationCollection applications = Application.retrieveAllApplications( + appType.getApplicationObjectType()); + applications.addOrder("title"); + + return new AppIterator(applications); + } else if (node instanceof ApplicationInstanceTreeNode) { + return null; + } else { + throw new IllegalArgumentException( + "The ApplicationTreeModel can only work with ApplicationTypeTreeNodes and" + + "ApplicationInstanceTreeNodes."); + } + } + + private ApplicationCollection retrieveApplicationInstances(final ApplicationType applicationType) { + final ApplicationCollection applications = Application.retrieveAllApplications(); + applications.addEqualsFilter("objectType", applicationType.getApplicationObjectType()); + + return applications; + } + + private class RootTreeNode implements TreeNode { + + public RootTreeNode() { + //Nothing + } + + public Object getKey() { + return "-1"; + } + + public Object getElement() { + return "/"; + } + + } + + private class AppTypesIterator implements Iterator { + + private final ApplicationTypeCollection appTypes; + + public AppTypesIterator(final ApplicationTypeCollection appTypes) { + this.appTypes = appTypes; + } + + public boolean hasNext() { + return appTypes.next(); + } + + public ApplicationTypeTreeNode next() { + return new ApplicationTypeTreeNode(appTypes.getApplicationType()); + } + + public void remove() { + throw new UnsupportedOperationException("Not supported."); + } + } + + private class AppIterator implements Iterator { + + private final ApplicationCollection applications; + + public AppIterator(final ApplicationCollection applications) { + this.applications = applications; + } + + public boolean hasNext() { + return applications.next(); + } + + public ApplicationInstanceTreeNode next() { + return new ApplicationInstanceTreeNode(applications.getApplication()); + } + + public void remove() { + throw new UnsupportedOperationException("Not supported."); + } + } +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModelBuilder.java b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModelBuilder.java new file mode 100644 index 000000000..e26570ae6 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTreeModelBuilder.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications.tree; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Tree; +import com.arsdigita.bebop.tree.TreeModel; +import com.arsdigita.bebop.tree.TreeModelBuilder; +import com.arsdigita.ui.admin.ApplicationsAdministrationTab; +import com.arsdigita.util.LockableImpl; + +/** + * The {@link TreeModelBuilder} creating the {@link TreeModel} for the applications tree used in + * {@link ApplicationsAdministrationTab}. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class ApplicationTreeModelBuilder extends LockableImpl implements TreeModelBuilder { + + public TreeModel makeModel(final Tree tree, final PageState state) { + tree.expand("-1", state); + return new ApplicationTreeModel(); + } +} diff --git a/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTypeTreeNode.java b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTypeTreeNode.java new file mode 100644 index 000000000..1e2a323f2 --- /dev/null +++ b/ccm-core/src/com/arsdigita/ui/admin/applications/tree/ApplicationTypeTreeNode.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 Jens Pelzetter + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.ui.admin.applications.tree; + +import com.arsdigita.bebop.tree.TreeNode; +import com.arsdigita.web.ApplicationType; + +/** + * Tree Node implementation for the Application Tree in the Application + * admin tab. + * + * @author Jens Pelzetter + * @version $Id$ + */ +public class ApplicationTypeTreeNode implements TreeNode { + + private final ApplicationType applicationType; + + public ApplicationTypeTreeNode(final ApplicationType applicationType) { + this.applicationType = applicationType; + } + + public ApplicationType getApplicationType() { + return applicationType; + } + + public Object getKey() { + return applicationType.getApplicationObjectType(); + } + + public Object getElement() { + return applicationType.getTitle(); + } + +}