/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.binding.form.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.context.support.MessageSourceAccessor;
import org.valkyriercp.binding.form.FieldFace;
import org.valkyriercp.binding.form.FormModel;
import org.valkyriercp.core.support.LabelInfo;
import org.valkyriercp.image.IconSource;
import org.valkyriercp.util.ReflectiveVisitorHelper;
import javax.swing.*;
/**
* <p>
* The various properties of the FieldFace are resolved from a message source using message codes. These codes where
* generated by a {@link MessageCodeStrategy}. If no other {@link MessageCodeStrategy} is defined an instance of
* {@link DefaultMessageCodeStrategy} will be used
*
* @author Oliver Hutchison
* @author Mathias Broekelmann
*/
public class MessageSourceFieldFaceSource extends CachingFieldFaceSource {
private static final Log log = LogFactory.getLog(MessageSourceFieldFaceSource.class);
/**
* Name for the FieldFace's <code>displayName</code> property.
*/
private static final String[] DISPLAY_NAME_PROPERTY = { "displayName" };
/**
* Name for the FieldFace's <code>caption</code> property.
*/
private static final String[] CAPTION_PROPERTY = { "caption" };
/**
* Name for the FieldFace's <code>description</code> property.
*/
private static final String[] DESCRIPTION_PROPERTY = { "description" };
/**
* Name for the FieldFace's <code>labelInfo</code> property.
*/
private static final String[] ENCODED_LABEL_PROPERTY = { "label", "" };
/**
* Name for the FieldFace's <code>icon</code> property.
*/
private static final String[] ICON_PROPERTY = { "icon" };
@Autowired
private MessageSourceAccessor messageSourceAccessor;
private MessageCodeStrategy messageKeyStrategy;
@Autowired
private IconSource iconSource;
private final ReflectiveVisitorHelper visitorHelper = new ReflectiveVisitorHelper();
/**
* Constructs a new MessageSourcePropertyFaceDescriptorSource.
*/
public MessageSourceFieldFaceSource() {
}
/**
* Set the message source that will be used to resolve the FieldFace's properties.
*/
public void setMessageSourceAccessor(MessageSourceAccessor messageSourceAccessor) {
this.messageSourceAccessor = messageSourceAccessor;
}
protected MessageSourceAccessor getMessageSourceAccessor() {
return messageSourceAccessor;
}
/**
* Set the icon source that will be used to resolve the FieldFace's icon property.
*/
public void setIconSource(IconSource iconSource) {
this.iconSource = iconSource;
}
protected IconSource getIconSource() {
return iconSource;
}
/**
* Returns the value of the required property of the FieldFace. Delegates to the getMessageKeys for the message key
* generation strategy. This method uses </code>[contextId + "." + ] fieldPath [ + "." + faceDescriptorProperty[0]]</code>
* for the default value
*/
protected String getMessage(String contextId, String fieldPath, String[] faceDescriptorProperty) {
String[] keys = getMessageKeys(contextId, fieldPath, faceDescriptorProperty);
return getMessageSourceAccessor().getMessage(new DefaultMessageSourceResolvable(keys, null, keys[0]));
}
/**
* Returns the value of the required property of the FieldFace. Delegates to the getMessageKeys for the message key
* generation strategy.
*/
protected String getMessage(String contextId, String fieldPath, String[] faceDescriptorProperties,
String defaultValue) {
String[] keys = getMessageKeys(contextId, fieldPath, faceDescriptorProperties);
try {
return getMessageSourceAccessor().getMessage(new DefaultMessageSourceResolvable(keys, null, defaultValue));
} catch (NoSuchMessageException e) {
if (log.isDebugEnabled()) {
log.debug(e.getMessage());
}
return null;
}
}
/**
* Returns an array of message keys that are used to resolve the required property of the FieldFace. The property
* will be resolved from the message source using the returned message keys in order.
* <p>
* Subclasses my override this method to provide an alternative to the default message key generation strategy.
*/
protected String[] getMessageKeys(String contextId, String fieldPath, String[] faceDescriptorProperties) {
return getMessageKeyStrategy().getMessageCodes(contextId, fieldPath, faceDescriptorProperties);
}
protected FieldFace loadFieldFace(String field, String contextId) {
String caption = getMessage(contextId, field, CAPTION_PROPERTY, null);
String description = getMessage(contextId, field, DESCRIPTION_PROPERTY, null);
String encodedLabel = getMessage(contextId, field, ENCODED_LABEL_PROPERTY);
if (encodedLabel == null) {
// try loading the default value
encodedLabel = getMessage(contextId, field, null);
}
String iconName = getMessage(contextId, field, ICON_PROPERTY, null);
Icon icon = null;
if (iconName != null) {
icon = getIconSource().getIcon(iconName);
}
LabelInfo labelInfo = LabelInfo.valueOf(encodedLabel);
String displayName = getMessage(contextId, field, DISPLAY_NAME_PROPERTY, labelInfo.getText());
return new DefaultFieldFace(displayName, caption, description, labelInfo, icon);
}
protected FieldFace loadFieldFace(String field, Object context) {
String contextId = (String) visitorHelper.invokeVisit(this, context);
return loadFieldFace(field, contextId);
}
public MessageCodeStrategy getMessageKeyStrategy() {
if (messageKeyStrategy == null) {
messageKeyStrategy = new DefaultMessageCodeStrategy();
}
return messageKeyStrategy;
}
public void setMessageKeyStrategy(MessageCodeStrategy messageKeyStrategy) {
this.messageKeyStrategy = messageKeyStrategy;
}
// visit methods for getting a context id from various context instances
String visit(FormModel formModel) {
return formModel.getId();
}
String visit(CharSequence contextId) {
return contextId.toString();
}
String visitNull() {
return null;
}
}