org.obiba.onyx.wicket.model.MagmaStringResourceModel.java Source code

Java tutorial

Introduction

Here is the source code for org.obiba.onyx.wicket.model.MagmaStringResourceModel.java

Source

/*******************************************************************************
 * Copyright (c) 2011 OBiBa. All rights reserved.
 *  
 * This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0.
 *  
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package org.obiba.onyx.wicket.model;

import java.util.Locale;

import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IChainingModel;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IModel;
import org.obiba.magma.Attribute;
import org.obiba.magma.Category;
import org.obiba.magma.Value;
import org.obiba.magma.Variable;
import org.obiba.magma.type.TextType;
import org.obiba.onyx.core.data.VariableDataSource;
import org.obiba.onyx.core.domain.participant.Participant;
import org.obiba.onyx.magma.OnyxAttributeHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A string resource model to resolved magma variables references in strings. Example of string that will be resolved:
 * 
 * <pre>
 *   You must select the $('ContraIndications:ArmSideChosen') Arm to measure the blood pressure.
 * </pre>
 * 
 * Supports value sequences display and localisation of category names.
 */
public abstract class MagmaStringResourceModel extends AbstractReadOnlyModel<String>
        implements IChainingModel<String> {

    private static final long serialVersionUID = 1L;

    private static final Logger log = LoggerFactory.getLogger(MagmaStringResourceModel.class);

    private Object target;

    public MagmaStringResourceModel(IModel<?> targetModel) {
        super();
        this.target = targetModel;
    }

    public MagmaStringResourceModel(String target) {
        super();
        this.target = target;
    }

    /**
     * Get the Participant from which value set will be retrieved.
     * @return
     */
    protected abstract Participant getParticipant();

    /**
     * Get the locale in which labels should be retrieved.
     * @return
     */
    protected abstract Locale getLocale();

    /**
     * Get the table context to resolve variable not fully qualified paths.
     * @return
     */
    protected abstract String getTableContext();

    @Override
    public String getObject() {
        String message;
        if (target instanceof IModel<?>) {
            Object obj = ((IModel<?>) target).getObject();
            message = (obj != null ? obj.toString() : null);
        } else {
            message = (String) target;
        }

        return message != null ? resolveVariableValuesInMessage(message, getTableContext(), getLocale()) : "";
    }

    @Override
    public void detach() {
        // Detach nested object if it's a detachable
        if (target instanceof IDetachable) {
            ((IDetachable) target).detach();
        }
    }

    @Override
    public void setChainedModel(IModel<?> model) {
        target = model;
    }

    @Override
    public IModel<?> getChainedModel() {
        if (target instanceof IModel) {
            return (IModel<?>) target;
        }
        return null;
    }

    private String resolveVariableValuesInMessage(String message, String tableContext, Locale locale) {
        String msg = message;
        // Look for variable references and replace by the value as a string
        try {
            int refIndex = msg.indexOf("$('");
            while (refIndex != -1) {
                int refEndIndex = msg.indexOf("')", refIndex);
                String path = msg.substring(refIndex + 3, refEndIndex);
                if (!path.contains(":")) {
                    path = tableContext + ":" + path;
                }
                VariableDataSource varDs = new VariableDataSource(path);
                Value value = varDs.getValue(getParticipant());

                String dataStr = getValueAsString(varDs, value, locale);
                msg = msg.substring(0, refIndex) + dataStr + msg.substring(refEndIndex + 2, msg.length());
                refIndex = msg.indexOf("$('");
            }
        } catch (Exception e) {
            log.error("Error while resolving variable values in: " + message, e);
        }
        return msg;
    }

    //
    // Methods
    //

    private String getValueAsString(VariableDataSource varDs, Value value, Locale locale) {
        if (value == null || value.isNull())
            return "";

        String dataStr = value.toString();
        if (value.getValueType().equals(TextType.get())) {
            Variable variable = varDs.getVariable();
            if (!value.isSequence()) {
                dataStr = getValueAsLabel(variable, value, locale);
            } else {
                StringBuffer buff = new StringBuffer();
                buff.append("<ul>");
                for (Value val : value.asSequence().getValues()) {
                    buff.append("<li>").append(getValueAsLabel(variable, val, locale)).append("</li>");
                }
                buff.append("</ul>");
                dataStr = buff.toString();
            }
        }
        return dataStr;
    }

    private String getValueAsLabel(Variable variable, Value value, Locale locale) {
        if (value == null || value.getValue() == null)
            return "";

        String valueStr = value.getValue().toString();
        if (variable.hasCategories()) {
            for (Category category : variable.getCategories()) {
                if (category.getName().equals(valueStr)) {
                    return getCategoryLabel(category, locale);
                }
            }
        }
        return valueStr;
    }

    private String getCategoryLabel(Category category, Locale locale) {
        if (category.hasAttribute(OnyxAttributeHelper.LABEL, locale)) {
            Attribute attr = category.getAttribute(OnyxAttributeHelper.LABEL, locale);
            if (attr.getValue() != null) {
                return attr.getValue().toString();
            }
        }
        return category.getName();
    }
}