001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.application.config;
017    
018    import java.awt.Color;
019    import java.awt.Image;
020    import java.util.Locale;
021    
022    import javax.swing.Icon;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    import org.springframework.beans.BeansException;
027    import org.springframework.beans.factory.config.BeanPostProcessor;
028    import org.springframework.context.MessageSource;
029    import org.springframework.context.NoSuchMessageException;
030    import org.springframework.richclient.application.ApplicationServicesLocator;
031    import org.springframework.richclient.application.ServiceNotFoundException;
032    import org.springframework.richclient.command.config.CommandButtonIconInfo;
033    import org.springframework.richclient.command.config.CommandButtonLabelInfo;
034    import org.springframework.richclient.command.config.CommandIconConfigurable;
035    import org.springframework.richclient.command.config.CommandLabelConfigurable;
036    import org.springframework.richclient.core.ColorConfigurable;
037    import org.springframework.richclient.core.DescriptionConfigurable;
038    import org.springframework.richclient.core.LabelConfigurable;
039    import org.springframework.richclient.core.LabelInfo;
040    import org.springframework.richclient.core.SecurityControllable;
041    import org.springframework.richclient.core.TitleConfigurable;
042    import org.springframework.richclient.image.IconSource;
043    import org.springframework.richclient.image.ImageSource;
044    import org.springframework.richclient.image.NoSuchImageResourceException;
045    import org.springframework.richclient.image.config.IconConfigurable;
046    import org.springframework.richclient.image.config.ImageConfigurable;
047    import org.springframework.richclient.security.SecurityController;
048    import org.springframework.richclient.security.SecurityControllerManager;
049    import org.springframework.richclient.util.Assert;
050    import org.springframework.util.StringUtils;
051    
052    /**
053     * The default implementation of the {@link ApplicationObjectConfigurer}
054     * interface.
055     * 
056     * This class makes use of several application services in order to determine
057     * the property values to be applied to objects being configured. For example,
058     * some string properties will be retrieved from the application's message
059     * resource bundle using a {@link MessageSource}. To configure an object with
060     * images and icons, an {@link ImageSource} and {@link IconSource} respectively
061     * will be used. Subclasses can modify this behaviour by overriding the
062     * {@link #configure(Object, String)} method but it may be more convenient to
063     * override some of the various methods that deal specificly with objects that
064     * implement certain 'configurable' interfaces, such as
065     * {@link LabelConfigurable} or {@link TitleConfigurable}. See the javadoc of
066     * the {@link #configure(Object, String)} method for more details.
067     * 
068     * 
069     * @author Keith Donald
070     * @author Kevin Stembridge
071     */
072    public class DefaultApplicationObjectConfigurer implements ApplicationObjectConfigurer, BeanPostProcessor {
073    
074            /**
075             * The key fragment used to retrieve the <i>pressed</i> icon for a given
076             * object.
077             */
078            public static final String PRESSED_ICON_KEY = "pressedIcon";
079    
080            /**
081             * The key fragment used to retrieve the <i>disabled</i> icon for a given
082             * object.
083             */
084            public static final String DISABLED_ICON_KEY = "disabledIcon";
085    
086            /**
087             * The key fragment used to retrieve the <i>rollover</i> icon for a given
088             * object.
089             */
090            public static final String ROLLOVER_ICON_KEY = "rolloverIcon";
091    
092            /**
093             * The key fragment used to retrieve the <i>selected</i> icon for a given
094             * object.
095             */
096            public static final String SELECTED_ICON_KEY = "selectedIcon";
097    
098            /** The key fragment used to retrieve the icon for a given object. */
099            public static final String ICON_KEY = "icon";
100    
101            /** The key fragment used to retrieve the image for a given object. */
102            public static final String IMAGE_KEY = "image";
103    
104            /** The key fragment used to retrieve the description for a given object. */
105            public static final String DESCRIPTION_KEY = "description";
106    
107            /** The key fragment used to retrieve the caption for a given object. */
108            public static final String CAPTION_KEY = "caption";
109    
110            /** The key fragment used to retrieve the title for a given object. */
111            public static final String TITLE_KEY = "title";
112    
113            /** The key fragment used to retrieve the label for a given object. */
114            public static final String LABEL_KEY = "label";
115    
116            /** Class logger, available to subclasses. */
117            protected final Log logger = LogFactory.getLog(getClass());
118    
119            private boolean loadOptionalIcons = true;
120    
121            private MessageSource messageSource;
122    
123            private ImageSource imageSource;
124    
125            private IconSource iconSource;
126    
127            private SecurityControllerManager securityControllerManager;
128    
129            /**
130             * Creates a new {@code DefaultApplicationObjectConfigurer} that will obtain
131             * required services from the application services locator.
132             */
133            public DefaultApplicationObjectConfigurer() {
134                    // do nothing
135            }
136    
137            /**
138             * Creates a new {@code DefaultApplicationObjectConfigurer} that will use
139             * the given message source. Other application services will be retrieved
140             * using the application services locator.
141             * 
142             * @param messageSource The message source. May be null.
143             */
144            public DefaultApplicationObjectConfigurer(MessageSource messageSource) {
145                    this(messageSource, null, null, null);
146            }
147    
148            /**
149             * Creates a new {@code DefaultApplicationObjectConfigurer} that will use
150             * the given message and image sources. Other application services will be
151             * retrieved using the application services locator.
152             * 
153             * @param messageSource The message source. May be null.
154             * @param imageSource The image source. May be null.
155             */
156            public DefaultApplicationObjectConfigurer(MessageSource messageSource, ImageSource imageSource) {
157                    this(messageSource, imageSource, null, null);
158            }
159    
160            /**
161             * Creates a new {@code DefaultApplicationObjectConfigurer} that will use
162             * the given message, image and icon sources. If any of these services are
163             * null, they will be retrieved using the application services locator.
164             * 
165             * @param messageSource The message source. May be null.
166             * @param imageSource The image source. May be null.
167             * @param iconSource The icon source. May be null.
168             * @param securityControllerManager The security controller manager. May be
169             * null.
170             */
171            public DefaultApplicationObjectConfigurer(MessageSource messageSource, ImageSource imageSource,
172                            IconSource iconSource, SecurityControllerManager securityControllerManager) {
173    
174                    this.messageSource = messageSource;
175                    this.imageSource = imageSource;
176                    this.iconSource = iconSource;
177                    this.securityControllerManager = securityControllerManager;
178    
179            }
180    
181            /**
182             * Sets the flag that determines if optional icons will be loaded for any
183             * {@link CommandIconConfigurable} objects that are configured by this
184             * instance. The default is true.
185             * 
186             * @param loadOptionalIcons The flag to load optional options.
187             */
188            public void setLoadOptionalIcons(boolean loadOptionalIcons) {
189                    this.loadOptionalIcons = loadOptionalIcons;
190            }
191    
192            /**
193             * Returns this instance's message source. If a source was not provided at
194             * construction, it will be retrieved by the application services locator.
195             * 
196             * @return The message source, never null.
197             * 
198             * @throws ServiceNotFoundException if a source was not provided at
199             * construction time and the application services locator cannot find an
200             * instance of a message source.
201             */
202            protected MessageSource getMessageSource() {
203    
204                    if (messageSource == null) {
205                            messageSource = (MessageSource) ApplicationServicesLocator.services().getService(MessageSource.class);
206                    }
207    
208                    return messageSource;
209    
210            }
211    
212            /**
213             * Returns this instance's icon source. If a source was not provided at
214             * construction, it will be retrieved by the application services locator.
215             * 
216             * @return The icon source, never null.
217             * 
218             * @throws ServiceNotFoundException if a source was not provided at
219             * construction time and the application services locator cannot find an
220             * instance of an icon source.
221             */
222            protected IconSource getIconSource() {
223    
224                    if (iconSource == null) {
225                            iconSource = (IconSource) ApplicationServicesLocator.services().getService(IconSource.class);
226                    }
227    
228                    return iconSource;
229    
230            }
231    
232            /**
233             * Returns this instance's image source. If a source was not provided at
234             * construction, it will be retrieved by the application services locator.
235             * 
236             * @return The image source, never null.
237             * 
238             * @throws ServiceNotFoundException if a source was not provided at
239             * construction time and the application services locator cannot find an
240             * instance of an image source.
241             */
242            protected ImageSource getImageSource() {
243    
244                    if (imageSource == null) {
245                            imageSource = (ImageSource) ApplicationServicesLocator.services().getService(ImageSource.class);
246                    }
247    
248                    return imageSource;
249    
250            }
251    
252            /**
253             * Returns this instance's security controller manager. If the security
254             * manager was not provided at construction, it will be retrieved by the
255             * application services locator.
256             * 
257             * @return The security controller manager, never null.
258             * 
259             * @throws ServiceNotFoundException if a security controller manager was not
260             * provided at construction time and the application services locator cannot
261             * find an instance of the service.
262             */
263            protected SecurityControllerManager getSecurityControllerManager() {
264    
265                    if (securityControllerManager == null) {
266                            securityControllerManager = (SecurityControllerManager) ApplicationServicesLocator.services().getService(
267                                            SecurityControllerManager.class);
268                    }
269    
270                    return securityControllerManager;
271    
272            }
273    
274            /**
275             * Configures the given object according to the interfaces that it
276             * implements.
277             * 
278             * <p>
279             * This implementation forwards the object to the following overridable
280             * methods in the order listed. Subclasses can use these methods as hooks to
281             * modify the default configuration behaviour without having to override
282             * this method entirely.
283             * 
284             * <ul>
285             * <li>{@link #configureTitle(TitleConfigurable, String)}</li>
286             * <li>{@link #configureLabel(LabelConfigurable, String)}</li>
287             * <li>{@link #configureCommandLabel(CommandLabelConfigurable, String)}</li>
288             * <li>{@link #configureDescription(DescriptionConfigurable, String)}</li>
289             * <li>{@link #configureImage(ImageConfigurable, String)}</li>
290             * <li>{@link #configureIcon(IconConfigurable, String)}</li>
291             * <li>{@link #configureCommandIcons(CommandIconConfigurable, String)}</li>
292             * <li>{@link #configureSecurityController(SecurityControllable, String)}</li>
293             * </ul>
294             * </p>
295             * 
296             * @param object The object to be configured. May be null.
297             * @param objectName The name for the object, expected to be unique within
298             * the application. If {@code object} is not null, then {@code objectName}
299             * must also be non-null.
300             * 
301             * @throws IllegalArgumentException if {@code object} is not null, but
302             * {@code objectName} is null.
303             * 
304             */
305            public void configure(Object object, String objectName) {
306    
307                    if (object == null) {
308                            logger.debug("object to be configured is null");
309                            return;
310                    }
311    
312                    Assert.required(objectName, "objectName");
313    
314                    if (object instanceof TitleConfigurable) {
315                            configureTitle((TitleConfigurable) object, objectName);
316                    }
317    
318                    if (object instanceof LabelConfigurable) {
319                            configureLabel((LabelConfigurable) object, objectName);
320                    }
321                    
322                    if (object instanceof ColorConfigurable) {
323                            configureColor((ColorConfigurable)object, objectName);
324                    }
325    
326                    if (object instanceof CommandLabelConfigurable) {
327                            configureCommandLabel((CommandLabelConfigurable) object, objectName);
328                    }
329    
330                    if (object instanceof DescriptionConfigurable) {
331                            configureDescription((DescriptionConfigurable) object, objectName);
332                    }
333    
334                    if (object instanceof ImageConfigurable) {
335                            configureImage((ImageConfigurable) object, objectName);
336                    }
337    
338                    if (object instanceof IconConfigurable) {
339                            configureIcon((IconConfigurable) object, objectName);
340                    }
341    
342                    if (object instanceof CommandIconConfigurable) {
343                            configureCommandIcons((CommandIconConfigurable) object, objectName);
344                    }
345    
346                    if (object instanceof SecurityControllable) {
347                            configureSecurityController((SecurityControllable) object, objectName);
348                    }
349    
350            }
351    
352            /**
353             * Sets the title of the given object. The title is loaded from this
354             * instance's {@link MessageSource} using a message code in the format
355             * 
356             * <pre>
357             *                     &lt;objectName&gt;.title
358             * </pre>
359             * 
360             * @param configurable The object to be configured. Must not be null.
361             * @param objectName The name of the configurable object, unique within the
362             * application. Must not be null.
363             * 
364             * @throws IllegalArgumentException if either argument is null.
365             */
366            protected void configureTitle(TitleConfigurable configurable, String objectName) {
367                    Assert.required(configurable, "configurable");
368                    Assert.required(objectName, "objectName");
369    
370                    String title = loadMessage(objectName + "." + TITLE_KEY);
371    
372                    if (StringUtils.hasText(title)) {
373                            configurable.setTitle(title);
374                    }
375            }
376    
377            /**
378             * Sets the {@link LabelInfo} of the given object. The label info is created
379             * after loading the encoded label string from this instance's
380             * {@link MessageSource} using a message code in the format
381             * 
382             * <pre>
383             *                     &lt;objectName&gt;.label
384             * </pre>
385             * 
386             * @param configurable The object to be configured. Must not be null.
387             * @param objectName The name of the configurable object, unique within the
388             * application. Must not be null.
389             * 
390             * @throws IllegalArgumentException if either argument is null.
391             */
392            protected void configureLabel(LabelConfigurable configurable, String objectName) {
393                    Assert.required(configurable, "configurable");
394                    Assert.required(objectName, "objectName");
395    
396                    String labelStr = loadMessage(objectName + "." + LABEL_KEY);
397    
398                    if (StringUtils.hasText(labelStr)) {
399                            LabelInfo labelInfo = LabelInfo.valueOf(labelStr);
400                            configurable.setLabelInfo(labelInfo);
401                    }
402            }
403    
404            /**
405             * Sets the foreground and background colours of the given object.
406             * Use the following message codes:
407             * 
408             * <pre>
409             * &lt;objectName&gt;.foreground
410             * &lt;objectName&gt;.background
411             * </pre>
412             * 
413             * @param configurable The object to be configured. Must not be null.
414             * @param objectName The name of the configurable object, unique within the
415             * application. Must not be null.
416             * 
417             * @throws IllegalArgumentException if either argument is null.
418             */
419            protected void configureColor(ColorConfigurable configurable, String objectName) {
420                    Assert.required(configurable, "configurable");
421                    Assert.required(objectName, "objectName");
422    
423                    Color color = loadColor(objectName + ".foreground");
424                    if (color != null)
425                            configurable.setForeground(color);
426                    
427                    color = loadColor(objectName + ".background");
428                    if (color != null)
429                            configurable.setBackground(color);
430            }
431            
432            /**
433             * Sets the {@link CommandButtonLabelInfo} of the given object. The label
434             * info is created after loading the encoded label string from this
435             * instance's {@link MessageSource} using a message code in the format
436             * 
437             * <pre>
438             *   &lt;objectName&gt;.label
439             * </pre>
440             * 
441             * @param configurable The object to be configured. Must not be null.
442             * @param objectName The name of the configurable object, unique within the
443             * application. Must not be null.
444             * 
445             * @throws IllegalArgumentException if either argument is null.
446             */
447            protected void configureCommandLabel(CommandLabelConfigurable configurable, String objectName) {
448                    Assert.required(configurable, "configurable");
449                    Assert.required(objectName, "objectName");
450    
451                    String labelStr = loadMessage(objectName + "." + LABEL_KEY);
452    
453                    if (StringUtils.hasText(labelStr)) {
454                            CommandButtonLabelInfo labelInfo = CommandButtonLabelInfo.valueOf(labelStr);
455                            configurable.setLabelInfo(labelInfo);
456                    }
457            }
458    
459            /**
460             * Sets the description and caption of the given object. These values are
461             * loaded from this instance's {@link MessageSource} using message codes in
462             * the format
463             * 
464             * <pre>
465             *   &lt;objectName&gt;.description
466             * </pre>
467             * 
468             * and
469             * 
470             * <pre>
471             *   &lt;objectName&gt;.caption
472             * </pre>
473             * 
474             * respectively.
475             * 
476             * @param configurable The object to be configured. Must not be null.
477             * @param objectName The name of the configurable object, unique within the
478             * application. Must not be null.
479             * 
480             * @throws IllegalArgumentException if either argument is null.
481             */
482            protected void configureDescription(DescriptionConfigurable configurable, String objectName) {
483                    Assert.required(configurable, "configurable");
484                    Assert.required(objectName, "objectName");
485    
486                    String caption = loadMessage(objectName + "." + CAPTION_KEY);
487    
488                    if (StringUtils.hasText(caption)) {
489                            configurable.setCaption(caption);
490                    }
491    
492                    String description = loadMessage(objectName + "." + DESCRIPTION_KEY);
493    
494                    if (StringUtils.hasText(description)) {
495                            configurable.setDescription(description);
496                    }
497    
498            }
499    
500            /**
501             * Sets the image of the given object. The image is loaded from this
502             * instance's {@link ImageSource} using a key in the format
503             * 
504             * <pre>
505             *   &lt;objectName&gt;.image
506             * </pre>
507             * 
508             * If the image source cannot find an image under that key, the object's
509             * image will be set to null.
510             * 
511             * @param configurable The object to be configured. Must not be null.
512             * @param objectName The name of the configurable object, unique within the
513             * application. Must not be null.
514             * 
515             * @throws IllegalArgumentException if either argument is null.
516             */
517            protected void configureImage(ImageConfigurable configurable, String objectName) {
518                    Assert.required(configurable, "configurable");
519                    Assert.required(objectName, "objectName");
520    
521                    Image image = loadImage(objectName, IMAGE_KEY);
522    
523                    if (image != null) {
524                            configurable.setImage(image);
525                    }
526            }
527    
528            /**
529             * Sets the icon of the given object. The icon is loaded from this
530             * instance's {@link IconSource} using a key in the format
531             * 
532             * <pre>
533             *   &lt;objectName&gt;.icon
534             * </pre>
535             * 
536             * If the icon source cannot find an icon under that key, the object's icon
537             * will be set to null.
538             * 
539             * @param configurable The object to be configured. Must not be null.
540             * @param objectName The name of the configurable object, unique within the
541             * application. Must not be null.
542             * 
543             * @throws IllegalArgumentException if either argument is null.
544             */
545            protected void configureIcon(IconConfigurable configurable, String objectName) {
546                    Assert.required(configurable, "configurable");
547                    Assert.required(objectName, "objectName");
548    
549                    Icon icon = loadIcon(objectName, ICON_KEY);
550    
551                    if (icon != null) {
552                            configurable.setIcon(icon);
553                    }
554            }
555    
556            /**
557             * Sets the icons of the given object.
558             * 
559             * <p>
560             * The icons are loaded from this instance's {@link IconSource}. using a
561             * key in the format
562             * </p>
563             * 
564             * <pre>
565             *   &lt;objectName&gt;.someIconType
566             * </pre>
567             * 
568             * <p>
569             * The keys used to retrieve large icons from the icon source are created by
570             * concatenating the given {@code objectName} with a dot (.), the text
571             * 'large' and then an icon type like so:
572             * </p>
573             * 
574             * <pre>
575             *  &lt;myObjectName&gt;.large.someIconType
576             * </pre>
577             * 
578             * <p>
579             * If the icon source cannot find an icon under that key, the object's icon
580             * will be set to null.
581             * </p>
582             * 
583             * <p>
584             * If the {@code loadOptionalIcons} flag is set to true (it is by default)
585             * all the following icon types will be used. If the flag is false, only the
586             * first will be used:
587             * </p>
588             * 
589             * <ul>
590             * <li>{@value #ICON_KEY}</li>
591             * <li>{@value #SELECTED_ICON_KEY}</li>
592             * <li>{@value #ROLLOVER_ICON_KEY}</li>
593             * <li>{@value #DISABLED_ICON_KEY}</li>
594             * <li>{@value #PRESSED_ICON_KEY}</li>
595             * </ul>
596             * 
597             * @param configurable The object to be configured. Must not be null.
598             * @param objectName The name of the configurable object, unique within the
599             * application. Must not be null.
600             * 
601             * @throws IllegalArgumentException if either argument is null.
602             */
603            protected void configureCommandIcons(CommandIconConfigurable configurable, String objectName) {
604                    Assert.required(configurable, "configurable");
605                    Assert.required(objectName, "objectName");
606                    setIconInfo(configurable, objectName, false);
607                    setIconInfo(configurable, objectName, true);
608            }
609    
610            /**
611             * Associates the given object with a security controller if it implements
612             * the {@link SecurityControllable} interface.
613             * @param object The object to be configured.
614             * @param objectName The name (id) of the object.
615             * @throws BeansException if a referenced security controller is not found
616             * or is of the wrong type
617             */
618            protected void configureSecurityController(SecurityControllable controllable, String objectName) {
619                    Assert.required(controllable, "controllable");
620                    Assert.required(objectName, "objectName");
621    
622                    String controllerId = controllable.getSecurityControllerId();
623    
624                    if (controllerId != null) {
625                            // Find the referenced controller.
626    
627                            if (logger.isDebugEnabled()) {
628                                    logger.debug("Lookup SecurityController with id [" + controllerId + "]");
629                            }
630    
631                            SecurityController controller = getSecurityControllerManager().getSecurityController(controllerId);
632    
633                            // And add the object to the controlled object set
634                            if (controller != null) {
635                                    if (logger.isDebugEnabled()) {
636                                            logger.debug("configuring SecurityControllable [" + objectName + "]; security controller id='"
637                                                            + controllerId + "'");
638                                    }
639                                    controller.addControlledObject(controllable);
640                            }
641                            else {
642                                    if (logger.isDebugEnabled()) {
643                                            logger.debug("configuring SecurityControllable [" + objectName
644                                                            + "]; no security controller for id='" + controllerId + "'");
645                                    }
646                            }
647                    }
648                    else {
649    
650                            if (logger.isDebugEnabled()) {
651                                    logger.debug("configuring SecurityControllable [" + objectName
652                                                    + "]; no security controller Id specified");
653                            }
654    
655                    }
656    
657            }
658    
659            protected void setIconInfo(CommandIconConfigurable object, String objectName, boolean large) {
660                    Assert.required(object, "object");
661                    Assert.required(objectName, "objectName");
662    
663                    Icon icon = loadIcon(objectName, ICON_KEY, large);
664    
665                    if (icon == null) {
666                            return;
667                    }
668    
669                    CommandButtonIconInfo iconInfo;
670    
671                    if (loadOptionalIcons) {
672                            Icon selectedIcon = loadIcon(objectName, SELECTED_ICON_KEY, large);
673                            Icon rolloverIcon = loadIcon(objectName, ROLLOVER_ICON_KEY, large);
674                            Icon disabledIcon = loadIcon(objectName, DISABLED_ICON_KEY, large);
675                            Icon pressedIcon = loadIcon(objectName, PRESSED_ICON_KEY, large);
676                            iconInfo = new CommandButtonIconInfo(icon, selectedIcon, rolloverIcon, disabledIcon, pressedIcon);
677                    }
678                    else {
679                            iconInfo = new CommandButtonIconInfo(icon);
680                    }
681    
682                    if (large) {
683                            object.setLargeIconInfo(iconInfo);
684                    }
685                    else {
686                            object.setIconInfo(iconInfo);
687                    }
688            }
689    
690            /**
691             * Configures the given object.
692             * @see #configure(Object, String)
693             */
694            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
695                    configure(bean, beanName);
696                    return bean;
697            }
698    
699            /**
700             * Attempts to load a {@link Color} by decoding the message that is found by
701             * looking up the given colorKey. Decoding is done by by
702             * {@link Color#decode(String)}.
703             * 
704             * @param colorKey The message code used to retrieve the colour code.
705             * @return the decoded {@link Color} or <code>null</code> if no colour could
706             * be decoded/found.
707             */
708            private Color loadColor(String colorKey) {
709                    String colorCode = loadMessage(colorKey);
710                    if (colorCode == null) {
711                            return null;
712                    }
713                    try {
714                            return Color.decode(colorCode);
715                    }
716                    catch (NumberFormatException nfe) {
717                            if (logger.isWarnEnabled()) {
718                                    logger.warn("Could not parse a valid Color from code [" + colorCode
719                                                    + "]. Ignoring and returning null.");
720                            }
721                            return null;
722                    }
723            }
724            
725            /**
726             * Attempts to load the message corresponding to the given message code
727             * using this instance's {@link MessageSource} and locale.
728             * 
729             * @param messageCode The message code that will be used to retrieve the
730             * message. Must not be null.
731             * @return The message for the given code, or null if the message code could
732             * not be found.
733             * 
734             * @throws IllegalArgumentException if {@code messageCode} is null.
735             */
736            private String loadMessage(String messageCode) {
737    
738                    Assert.required(messageCode, "messageCode");
739    
740                    if (logger.isDebugEnabled()) {
741                            logger.debug("Resolving label with code '" + messageCode + "'");
742                    }
743    
744                    try {
745                            return getMessageSource().getMessage(messageCode, null, getLocale());
746                    }
747                    catch (NoSuchMessageException e) {
748    
749                            if (logger.isInfoEnabled()) {
750                                    logger.info("The message source is unable to find message code [" + messageCode
751                                                    + "]. Ignoring and returning null.");
752                            }
753    
754                            return null;
755                    }
756    
757            }
758    
759            /**
760             * Returns the system default locale.
761             * 
762             * @return The system default locale, never null.
763             */
764            protected Locale getLocale() {
765                    return Locale.getDefault();
766            }
767    
768            private Icon loadIcon(String objectName, String iconType) {
769                    return loadIcon(objectName, iconType, false);
770            }
771    
772            private Icon loadIcon(String objectName, String iconType, boolean large) {
773                    String key = objectName + (large ? ".large." : ".") + iconType;
774                    return getIconSource().getIcon(key);
775            }
776    
777            private Image loadImage(String objectName, String imageType) {
778                    String key = objectName + "." + imageType;
779                    try {
780                            if (logger.isDebugEnabled()) {
781                                    logger.debug("Resolving optional image with code '" + key + "'");
782                            }
783                            return getImageSource().getImage(key);
784                    }
785                    catch (NoSuchImageResourceException e) {
786                            if (logger.isInfoEnabled()) {
787                                    logger.info("Labelable object's image '" + key + "' does not exist in image bundle; continuing...");
788                            }
789                            return null;
790                    }
791            }
792    
793            /**
794             * A default implemenation, performing no operation.
795             */
796            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
797                    return bean;
798            }
799    
800    }