From fad219c1fe6c289f860fea1defc587e52276c0d2 Mon Sep 17 00:00:00 2001 From: jensp Date: Thu, 10 Jul 2014 10:35:33 +0000 Subject: [PATCH] - Extended GlobalizedMessage: It is now possible to pass a custom ResourceBundle.Control instance to a GlobalizedMessage for controlling the loading of responsible ResourceBundle - Created RelationAttributeResourceBundle: A custom ResourceBundle.Control implementation which uses a RelationAttributeCollection as data source for creating a ListResourceBundle. This allows it to This allows it to use GlobalizedMessage when showing RelationAttribute values in Bebop Controls - Altered GenericOrganizationalUnitPersonAddForm to use GlobalizedMessage and RelationAttributeResourceControl git-svn-id: https://svn.libreccm.org/ccm/trunk@2746 8810af33-2d31-482b-a856-94f89814c4df --- ...elationAttributeResourceBundleControl.java | 46 +++++ ...enericOrganizationalUnitPersonAddForm.java | 79 ++++---- .../globalization/GlobalizedMessage.java | 170 ++++++++++-------- 3 files changed, 187 insertions(+), 108 deletions(-) create mode 100644 ccm-cms/src/com/arsdigita/cms/RelationAttributeResourceBundleControl.java diff --git a/ccm-cms/src/com/arsdigita/cms/RelationAttributeResourceBundleControl.java b/ccm-cms/src/com/arsdigita/cms/RelationAttributeResourceBundleControl.java new file mode 100644 index 000000000..7ae375e65 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/RelationAttributeResourceBundleControl.java @@ -0,0 +1,46 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package com.arsdigita.cms; + +import java.util.ListResourceBundle; +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * + * @author Jens Pelzetter + */ +public class RelationAttributeResourceBundleControl extends ResourceBundle.Control { + + @Override + public ResourceBundle newBundle(final String baseName, + final Locale locale, + final String format, + final ClassLoader classLoader, + final boolean reload) { + final RelationAttributeCollection values = new RelationAttributeCollection(baseName); + values.addLanguageFilter(locale.getLanguage()); + + final Object[][] contents = new Object[(int)values.size()][2]; + int i = 0; + while(values.next()) { + contents[i][0] = values.getKey(); + contents[i][1] = values.getName(); + i++; + } + + return new ListResourceBundle() { + + @Override + protected Object[][] getContents() { + return contents; + } + }; + + } + +} diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrganizationalUnitPersonAddForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrganizationalUnitPersonAddForm.java index 33c9a33ea..22a1feb85 100644 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrganizationalUnitPersonAddForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericOrganizationalUnitPersonAddForm.java @@ -38,6 +38,7 @@ import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.RelationAttribute; import com.arsdigita.cms.RelationAttributeCollection; +import com.arsdigita.cms.RelationAttributeResourceBundleControl; import com.arsdigita.cms.contenttypes.GenericOrganizationalUnit; import com.arsdigita.cms.contenttypes.GenericOrganizationalUnitPersonCollection; import com.arsdigita.cms.contenttypes.GenericPerson; @@ -45,6 +46,7 @@ import com.arsdigita.cms.contenttypes.util.ContenttypesGlobalizationUtil; import com.arsdigita.cms.ui.ItemSearchWidget; import com.arsdigita.cms.ui.authoring.BasicItemForm; import com.arsdigita.globalization.GlobalizationHelper; +import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.util.UncheckedWrapperException; import java.util.TooManyListenersException; import org.apache.log4j.Logger; @@ -56,13 +58,13 @@ import org.apache.log4j.Logger; * @version $Id$ */ public class GenericOrganizationalUnitPersonAddForm - extends BasicItemForm - implements FormProcessListener, - FormInitListener, - FormSubmissionListener { + extends BasicItemForm + implements FormProcessListener, + FormInitListener, + FormSubmissionListener { private static final Logger logger = Logger.getLogger( - GenericOrganizationalUnitPersonAddForm.class); + GenericOrganizationalUnitPersonAddForm.class); private GenericOrganizationalUnitPersonPropertiesStep m_step; private ItemSearchWidget m_itemSearch; private final String ITEM_SEARCH = "orgaunitPerson"; @@ -78,14 +80,14 @@ public class GenericOrganizationalUnitPersonAddForm @Override protected void addWidgets() { - // add(new Label(ContenttypesGlobalizationUtil.globalize( - // "cms.contenttypes.ui.genericorgaunit.select_person"))); + // add(new Label(ContenttypesGlobalizationUtil.globalize( + // "cms.contenttypes.ui.genericorgaunit.select_person"))); m_itemSearch = new ItemSearchWidget(ITEM_SEARCH, ContentType. findByAssociatedObjectType(getPersonType())); /*m_itemSearch.getItemField().addValidationListener( new NotNullValidationListener());*/ m_itemSearch.setLabel(ContenttypesGlobalizationUtil.globalize( - "cms.contenttypes.ui.genericorgaunit.select_person")); + "cms.contenttypes.ui.genericorgaunit.select_person")); m_itemSearch.setDisableCreatePane(false); add(this.m_itemSearch); @@ -93,15 +95,15 @@ public class GenericOrganizationalUnitPersonAddForm add(selectedPersonNameLabel); ParameterModel roleParam = new StringParameter( - GenericOrganizationalUnitPersonCollection.PERSON_ROLE); + GenericOrganizationalUnitPersonCollection.PERSON_ROLE); SingleSelect roleSelect = new SingleSelect(roleParam); roleSelect.setLabel(ContenttypesGlobalizationUtil.globalize( - "cms.contenttypes.ui.genericorgaunit.person.role")); + "cms.contenttypes.ui.genericorgaunit.person.role")); roleSelect.addValidationListener(new NotNullValidationListener()); roleSelect.addOption( - new Option("", - new Label(ContenttypesGlobalizationUtil - .globalize("cms.ui.select_one")))); + new Option("", + new Label(ContenttypesGlobalizationUtil + .globalize("cms.ui.select_one")))); try { roleSelect.addPrintListener(new PrintListener() { @@ -110,13 +112,18 @@ public class GenericOrganizationalUnitPersonAddForm final SingleSelect target = (SingleSelect) event.getTarget(); final RelationAttributeCollection roles = new RelationAttributeCollection( - getRoleAttributeName()); + getRoleAttributeName()); roles.addLanguageFilter(GlobalizationHelper.getNegotiatedLocale(). - getLanguage()); + getLanguage()); while (roles.next()) { RelationAttribute role; role = roles.getRelationAttribute(); - target.addOption(new Option(role.getKey(), role.getName())); + //target.addOption(new Option(role.getKey(), role.getName())); + target.addOption(new Option(role.getKey(), + new Label(new GlobalizedMessage( + role.getKey(), + getRoleAttributeName(), + new RelationAttributeResourceBundleControl())))); } } @@ -127,14 +134,14 @@ public class GenericOrganizationalUnitPersonAddForm add(roleSelect); final ParameterModel statusModel = new StringParameter( - GenericOrganizationalUnitPersonCollection.STATUS); + GenericOrganizationalUnitPersonCollection.STATUS); final SingleSelect statusSelect = new SingleSelect(statusModel); statusSelect.setLabel(ContenttypesGlobalizationUtil.globalize( - "cms.contenttypes.ui.genericorgaunit.person.status")); + "cms.contenttypes.ui.genericorgaunit.person.status")); statusSelect.addValidationListener(new NotNullValidationListener()); statusSelect.addOption(new Option("", new Label(ContenttypesGlobalizationUtil. - globalize("cms.ui.select_one")))); + globalize("cms.ui.select_one")))); try { statusSelect.addPrintListener(new PrintListener() { @@ -142,13 +149,17 @@ public class GenericOrganizationalUnitPersonAddForm public void prepare(final PrintEvent event) { final SingleSelect target = (SingleSelect) event.getTarget(); RelationAttributeCollection statusColl = new RelationAttributeCollection( - getStatusAttributeName()); + getStatusAttributeName()); statusColl.addLanguageFilter(GlobalizationHelper.getNegotiatedLocale(). - getLanguage()); + getLanguage()); while (statusColl.next()) { RelationAttribute status; status = statusColl.getRelationAttribute(); - target.addOption(new Option(status.getKey(), status.getName())); + //target.addOption(new Option(status.getKey(), status.getName())); + target.addOption(new Option(status.getKey(), + new Label(new GlobalizedMessage(status.getKey(), + getStatusAttributeName(), + new RelationAttributeResourceBundleControl())))); } } @@ -196,7 +207,7 @@ public class GenericOrganizationalUnitPersonAddForm FormData data = fse.getFormData(); PageState state = fse.getPageState(); GenericOrganizationalUnit orga = (GenericOrganizationalUnit) getItemSelectionModel(). - getSelectedObject(state); + getSelectedObject(state); if (this.getSaveCancelSection().getSaveButton().isSelected(state)) { @@ -210,9 +221,9 @@ public class GenericOrganizationalUnitPersonAddForm orga.addPerson(personToAdd, (String) data.get( - GenericOrganizationalUnitPersonCollection.PERSON_ROLE), + GenericOrganizationalUnitPersonCollection.PERSON_ROLE), (String) data.get( - GenericOrganizationalUnitPersonCollection.STATUS)); + GenericOrganizationalUnitPersonCollection.STATUS)); m_itemSearch.publishCreatedItem(data, personToAdd); } else { GenericOrganizationalUnitPersonCollection persons; @@ -226,9 +237,9 @@ public class GenericOrganizationalUnitPersonAddForm } persons.setRoleName((String) data.get( - GenericOrganizationalUnitPersonCollection.PERSON_ROLE)); + GenericOrganizationalUnitPersonCollection.PERSON_ROLE)); persons.setStatus((String) data.get( - GenericOrganizationalUnitPersonCollection.STATUS)); + GenericOrganizationalUnitPersonCollection.STATUS)); selector.setSelectedPerson(null); selector.setSelectedPersonRole(null); @@ -243,7 +254,7 @@ public class GenericOrganizationalUnitPersonAddForm public void submitted(FormSectionEvent fse) throws FormProcessException { if (this.getSaveCancelSection().getCancelButton().isSelected( - fse.getPageState())) { + fse.getPageState())) { selector.setSelectedPerson(null); selector.setSelectedPersonRole(null); selector.setSelectedPersonStatus(null); @@ -258,16 +269,16 @@ public class GenericOrganizationalUnitPersonAddForm final FormData data = fse.getFormData(); if ((selector.getSelectedPerson() == null) - && (data.get(ITEM_SEARCH) == null)) { + && (data.get(ITEM_SEARCH) == null)) { data.addError( - ContenttypesGlobalizationUtil.globalize( - "cms.contenttypes.ui.genericorgaunit.person.no_person_selected")); + ContenttypesGlobalizationUtil.globalize( + "cms.contenttypes.ui.genericorgaunit.person.no_person_selected")); return; } if (selector.getSelectedPerson() == null) { GenericOrganizationalUnit orga = (GenericOrganizationalUnit) getItemSelectionModel(). - getSelectedObject(state); + getSelectedObject(state); GenericPerson person = (GenericPerson) data.get(ITEM_SEARCH); @@ -294,8 +305,8 @@ public class GenericOrganizationalUnitPersonAddForm person.getID().toString()));*/ if (persons.size() > 0) { data.addError( - ContenttypesGlobalizationUtil.globalize( - "cms.contenttypes.ui.genericorgaunit.person.already_added")); + ContenttypesGlobalizationUtil.globalize( + "cms.contenttypes.ui.genericorgaunit.person.already_added")); } persons.close(); diff --git a/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java b/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java index b54b94afa..209f152e3 100755 --- a/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java +++ b/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java @@ -27,13 +27,12 @@ import org.apache.log4j.Logger; /** *

- * Represents a key into a ResourceBundle, a target ResourceBundle, and - * possibly an array of arguments to interpolate into the retrieved message - * using the MessageFormat class. + * Represents a key into a ResourceBundle, a target ResourceBundle, and possibly an array of + * arguments to interpolate into the retrieved message using the MessageFormat class. *

*

- * This class should be used in any situation where the application needs to - * output localizeable objects. + * This class should be used in any situation where the application needs to output localizeable + * objects. *

* * @see java.text.MessageFormat @@ -44,22 +43,28 @@ import org.apache.log4j.Logger; */ public class GlobalizedMessage { - /** Internal logger instance to faciliate debugging. Enable logging output - * by editing /WEB-INF/conf/log4j.properties int hte runtime environment - * and set com.arsdigita.globalization.GlobalizedMessage=DEBUG - * by uncommenting or adding the line. */ - private static final Logger LOGGER = Logger.getLogger(GlobalizedMessage - .class.getName()); + /** + * Internal logger instance to faciliate debugging. Enable logging output by editing + * /WEB-INF/conf/log4j.properties int hte runtime environment and set + * com.arsdigita.globalization.GlobalizedMessage=DEBUG by uncommenting or adding the line. + */ + private static final Logger LOGGER = Logger.getLogger(GlobalizedMessage.class.getName()); private String m_key = ""; private String m_bundleName = ""; + /** + * {@link ResourceBundle.Control} used by this {@code GlobalizedMessage} for looking up + * the ResourceBundle. Defaults to {@link ResourceBundle.Control#getNoFallbackControl(java.util.List)} + * to avoid that the locale of the server is taken into account. + */ + private ResourceBundle.Control rbControl = ResourceBundle.Control.getNoFallbackControl( + ResourceBundle.Control.FORMAT_DEFAULT); private Object[] m_args = null; /** *

- * Constructor. Takes in a key to be used to look up a message in the - * ResourceBundle for the current running application. The base name of - * the ResourceBundle to do the lookup in is retrieved from the - * ApplicationContext. + * Constructor. Takes in a key to be used to look up a message in the ResourceBundle for the + * current running application. The base name of the ResourceBundle to do the lookup in is + * retrieved from the ApplicationContext. *

* * @param key The key to use to look up a message in the ResourceBundle. @@ -71,8 +76,7 @@ public class GlobalizedMessage { /** *

- * Constructor. Takes in a key to be used to look up a message in the - * ResourceBundle specified. + * Constructor. Takes in a key to be used to look up a message in the ResourceBundle specified. *

* * @param key The key to use to look up a message in the ResourceBundle. @@ -85,16 +89,14 @@ public class GlobalizedMessage { /** *

- * Constructor. Takes in a key to be used to look up a message in the - * ResourceBundle for the current running application. The base name of - * the ResourceBundle to do the lookup in is retrieved from the - * ApplicationContext. Also takes in an Object[] of arguments to - * interpolate into the retrieved message using the MessageFormat class. + * Constructor. Takes in a key to be used to look up a message in the ResourceBundle for the + * current running application. The base name of the ResourceBundle to do the lookup in is + * retrieved from the ApplicationContext. Also takes in an Object[] of arguments to interpolate + * into the retrieved message using the MessageFormat class. *

* * @param key The key to use to look up a message in the ResourceBundle. - * @param args An Object[] of arguments to interpolate into the retrieved - * message. + * @param args An Object[] of arguments to interpolate into the retrieved message. */ public GlobalizedMessage(final String key, final Object[] args) { this(key); @@ -103,22 +105,49 @@ public class GlobalizedMessage { /** *

- * Constructor. Takes in a key to be used to look up a message in the - * ResourceBundle specified. Also takes in an Object[] of arguments to - * interpolate into the retrieved message using the MessageFormat class. + * Constructor. Takes in a key to be used to look up a message in the ResourceBundle specified. + * Also takes in an Object[] of arguments to interpolate into the retrieved message using the + * MessageFormat class. *

* * @param key The key to use to look up a message in the ResourceBundle. * @param bundleName The base name of the target ResourceBundle. - * @param args An Object[] of arguments to interpolate into the retrieved - * message. + * @param args An Object[] of arguments to interpolate into the retrieved message. */ - public GlobalizedMessage(final String key, - final String bundleName, + public GlobalizedMessage(final String key, + final String bundleName, final Object[] args) { this(key, bundleName); setArgs(args); } + + public GlobalizedMessage(final String key, + final ResourceBundle.Control rbControl) { + this(key); + this.rbControl = rbControl; + } + + public GlobalizedMessage(final String key, + final Object[] args, + final ResourceBundle.Control rbControl) { + this(key, args); + this.rbControl = rbControl; + } + + public GlobalizedMessage(final String key, + final String bundleName, + final ResourceBundle.Control rbControl) { + this(key, bundleName); + this.rbControl = rbControl; + } + + public GlobalizedMessage(final String key, + final String bundleName, + final Object[] args, + final ResourceBundle.Control rbControl) { + this(key, bundleName, args); + this.rbControl = rbControl; + } /** *

@@ -132,7 +161,7 @@ public class GlobalizedMessage { } /** - * + * * @param key */ private void setKey(final String key) { @@ -166,73 +195,64 @@ public class GlobalizedMessage { /** *

- * Localize this message. If no message is found the key is returned as - * the message. This is done so that developers or translators can see the - * messages that still need localization. + * Localize this message. If no message is found the key is returned as the message. This is + * done so that developers or translators can see the messages that still need localization. *

*

- * Any arguments this message has are interpolated into it using the - * java.text.MessageFormat class. + * Any arguments this message has are interpolated into it using the java.text.MessageFormat + * class. *

* - * @return Object Represents the localized version of this - * message. The reason this method returns an Object and - * not a String is because we might want to localize - * resources other than strings, such as icons or sound - * bites. Maybe this class should have been called - * GlobalizedObject? + * @return Object Represents the localized version of this message. The reason this method + * returns an Object and not a String is because we might want to localize resources other than + * strings, such as icons or sound bites. Maybe this class should have been called + * GlobalizedObject? */ public Object localize() { return localize(com.arsdigita.globalization.GlobalizationHelper - .getNegotiatedLocale()); + .getNegotiatedLocale()); } /** *

- * Localize this message according the specified request. If no message is - * found the key is returned as the message. This is done so that - * developers or translators can see the messages that still need - * localization. + * Localize this message according the specified request. If no message is found the key is + * returned as the message. This is done so that developers or translators can see the messages + * that still need localization. *

*

- * Any arguments this message has are interpolated into it using the - * java.text.MessageFormat class. + * Any arguments this message has are interpolated into it using the java.text.MessageFormat + * class. *

* * @param request The current running request. * - * @return Object Represents the localized version of this - * message. The reason this method returns an Object and - * not a String is because we might want to localize - * resources other than strings, such as icons or sound - * bites. Maybe this class should have been called - * GlobalizedObject? + * @return Object Represents the localized version of this message. The reason this method + * returns an Object and not a String is because we might want to localize resources other than + * strings, such as icons or sound bites. Maybe this class should have been called + * GlobalizedObject? */ public Object localize(final HttpServletRequest request) { return localize(com.arsdigita.globalization.GlobalizationHelper - .getNegotiatedLocale()); + .getNegotiatedLocale()); } /** *

- * Localize this message with the provided locale. If no message is - * found the key is returned as the message. This is done so that - * developers or translators can see the messages that still need - * localization. + * Localize this message with the provided locale. If no message is found the key is returned as + * the message. This is done so that developers or translators can see the messages that still + * need localization. *

*

- * Any arguments this message has are interpolated into it using the - * java.text.MessageFormat class. + * Any arguments this message has are interpolated into it using the java.text.MessageFormat + * class. *

* * @param locale The locale to try to use to localize this message. * - * @return Object Represents the localized version of this - * message. The reason this method returns an Object and - * not a String is because we might want to localize - * resources other than strings, such as icons or sound - * bites. Maybe this class should have been called - * GlobalizedObject? + * @return Object Represents the localized version of this message. The reason this method + * returns an Object and not a String is because we might want to localize resources other than + * strings, such as icons or sound bites. Maybe this class should have been called + * GlobalizedObject? */ public Object localize(final Locale locale) { Object message = getKey(); @@ -260,10 +280,13 @@ public class GlobalizedMessage { // Therefore, all what was to do was to change the call of getBundle here from // ResourceBundle#getBundle(String, Locale) to ResourceBundle#getBundle(String, Locale, ResourceControl) // with ResourceBundle.Control.getNoFallbackControl(List). + // jensp 2014-07-10: + // It is now possible to pass the custom implementation of ResourceBundle.Control to + // a GlobalizedMessage resourceBundle = ResourceBundle.getBundle( getBundleName(), - locale, - ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_DEFAULT)); + locale, + rbControl); } catch (MissingResourceException e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( @@ -304,9 +327,8 @@ public class GlobalizedMessage { /** * For debugging, not for localizing. * - * If you need a String, use an additional localize() to get an object - * and cast it to String. e.g. - * String label = (String) GlobalizedMessage(key,bundleName).localize(); + * If you need a String, use an additional localize() to get an object and cast it to String. + * e.g. String label = (String) GlobalizedMessage(key,bundleName).localize(); * * @return The contents in String form for debugging. */