com.google.gdt.eclipse.designer.model.property.DateTimeFormatPropertyEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gdt.eclipse.designer.model.property.DateTimeFormatPropertyEditor.java

Source

/*******************************************************************************
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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 com.google.gdt.eclipse.designer.model.property;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.eclipse.wb.core.controls.CCombo3;
import org.eclipse.wb.internal.core.model.property.GenericProperty;
import org.eclipse.wb.internal.core.model.property.IConfigurablePropertyObject;
import org.eclipse.wb.internal.core.model.property.Property;
import org.eclipse.wb.internal.core.model.property.editor.AbstractComboPropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.IValueSourcePropertyEditor;
import org.eclipse.wb.internal.core.model.property.editor.PropertyEditor;
import org.eclipse.wb.internal.core.model.util.ScriptUtils;
import org.eclipse.wb.internal.core.utils.reflect.CompositeClassLoader;
import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils;
import org.eclipse.wb.internal.core.utils.state.EditorState;

import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;

import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;

/**
 * {@link PropertyEditor} for editing DateTimeFormat.
 * 
 * @author sablin_aa
 * @coverage gwt.model.property
 */
public final class DateTimeFormatPropertyEditor extends AbstractComboPropertyEditor
        implements IValueSourcePropertyEditor, IConfigurablePropertyObject {
    private CompositeClassLoader m_loader;
    private Class<?> m_formatClass;
    private List<Method> m_formatMethods;
    private String m_extractScript;
    private String m_sourceTemplate;

    ////////////////////////////////////////////////////////////////////////////
    //
    // Constructor
    //
    ////////////////////////////////////////////////////////////////////////////
    public DateTimeFormatPropertyEditor() {
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Presentation
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    protected String getText(Property property) throws Exception {
        String text = getPattern(property);
        if (text == null) {
            Object value = property.getValue();
            if (value != null && value != Property.UNKNOWN_VALUE) {
                text = value.getClass().getCanonicalName();
            }
        }
        return text;
    }

    private String getPattern(Property property) throws Exception {
        Object value = extractFormat(property);
        if (value != null && m_formatClass.isAssignableFrom(value.getClass())) {
            return (String) ReflectionUtils.invokeMethod(value, "getPattern()");
        }
        return null;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Editing
    //
    ////////////////////////////////////////////////////////////////////////////
    @Override
    protected void addItems(Property property, CCombo3 combo) throws Exception {
        for (Method method : m_formatMethods) {
            combo.add(getMethodTitle(method));
        }
        combo.add("Custom...");
    }

    @Override
    protected void selectItem(Property property, CCombo3 combo) throws Exception {
        Object format = extractFormat(property);
        for (Method method : m_formatMethods) {
            if (format == method.invoke(m_formatClass)) {
                combo.setText(getMethodTitle(method));
                return;
            }
        }
        if (getPattern(property) != null) {
            combo.select(combo.getItemCount() - 1);
        }
    }

    @Override
    protected void toPropertyEx(Property property, CCombo3 combo, int index) throws Exception {
        if (index == m_formatMethods.size()) {
            // custom item selected
            InputDialog inputDialog = new InputDialog(combo.getShell(), "Date&time format",
                    "Enter date & time format pattern", getPattern(property), null);
            if (inputDialog.open() == Window.OK) {
                String pattern = inputDialog.getValue();
                Object value = ReflectionUtils.invokeMethod(m_formatClass, "getFormat(java.lang.String)", pattern);
                setPropertyExpression((GenericProperty) property, "getFormat(\"" + pattern + "\")", value);
            }
        } else {
            // standard selected
            Method method = m_formatMethods.get(index);
            setPropertyExpression((GenericProperty) property, method.getName() + "()",
                    method.invoke(m_formatClass));
        }
    }

    private void setPropertyExpression(GenericProperty property, String invocation, Object value) throws Exception {
        String source = ReflectionUtils.getFullyQualifiedName(m_formatClass, false) + "." + invocation;
        property.setExpression(getSourceByTemplate(source), value);
    }

    private String getSourceByTemplate(String source) {
        return (StringUtils.isEmpty(m_sourceTemplate) ? source
                : StringUtils.replace(m_sourceTemplate, "%value%", source)).trim();
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // IValueSourcePropertyEditor
    //
    ////////////////////////////////////////////////////////////////////////////
    public String getValueSource(Object value) throws Exception {
        if (value != null && m_formatClass.isAssignableFrom(value.getClass())) {
            String formatFullyQualifiedName = ReflectionUtils.getFullyQualifiedName(m_formatClass, false);
            // check for static formats
            for (Method method : m_formatMethods) {
                if (value == method.invoke(m_formatClass)) {
                    return getSourceByTemplate(formatFullyQualifiedName + "." + method.getName() + "()");
                }
            }
            // get custom format
            String customPattern = (String) ReflectionUtils.invokeMethod(value, "getPattern()");
            return getSourceByTemplate(formatFullyQualifiedName + ".getFormat(\"" + customPattern + "\")");
        }
        return null;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // IConfigurablePropertyObject
    //
    ////////////////////////////////////////////////////////////////////////////
    public void configure(EditorState state, Map<String, Object> parameters) throws Exception {
        m_loader = new CompositeClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                if (ReflectionUtils.class.getCanonicalName().equals(name)) {
                    return ReflectionUtils.class;
                }
                return super.loadClass(name);
            }
        };
        m_loader.add(state.getEditorLoader(), null);
        // get static formats
        {
            m_formatClass = m_loader.loadClass("com.google.gwt.i18n.client.DateTimeFormat");
            m_formatMethods = Lists.newArrayList();
            for (Method method : m_formatClass.getMethods()) {
                int modifiers = method.getModifiers();
                if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)
                        && method.getParameterTypes().length == 0 && method.getName().endsWith("Format")) {
                    m_formatMethods.add(method);
                }
            }
        }
        // extract script
        {
            final String EXTRACT_PARAM = "extract";
            if (parameters.containsKey(EXTRACT_PARAM)) {
                m_extractScript = (String) parameters.get(EXTRACT_PARAM);
            } else {
                m_extractScript = "";
            }
        }
        // source template
        {
            final String SOURCE_PARAM = "source";
            if (parameters.containsKey(SOURCE_PARAM)) {
                m_sourceTemplate = (String) parameters.get(SOURCE_PARAM);
            } else {
                m_sourceTemplate = "";
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Utils
    //
    ////////////////////////////////////////////////////////////////////////////
    /**
     * @return Extracted by script (if specified) date-time format object
     */
    private Object extractFormat(Property property) throws Exception {
        Object value = property.getValue();
        if (Property.UNKNOWN_VALUE == value) {
            return null;
        }
        if (!StringUtils.isEmpty(m_extractScript)) {
            Map<String, Object> variables = Maps.newTreeMap();
            ;
            variables.put("value", value);
            if (property instanceof GenericProperty) {
                variables.put("control", ((GenericProperty) property).getJavaInfo().getObject());
            }
            value = evaluate(m_extractScript, variables);
        }
        return value;
    }

    /**
     * @return evaluated object
     */
    private Object evaluate(String script, Map<String, Object> variables) throws Exception {
        if (m_loader == null) {
            return ScriptUtils.evaluate(script, variables);
        } else {
            return ScriptUtils.evaluate(m_loader, script, variables);
        }
    }

    /**
     * @return displaying title for format getter method
     */
    private String getMethodTitle(Method method) {
        return StringUtils.replace(method.getName(), "get", "");
    }
}