Java tutorial
/******************************************************************************* * 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", ""); } }