You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by cb...@apache.org on 2010/09/15 12:57:37 UTC
svn commit: r997274 - in /pivot/trunk:
core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java
tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Author: cbartlett
Date: Wed Sep 15 10:57:37 2010
New Revision: 997274
URL: http://svn.apache.org/viewvc?rev=997274&view=rev
Log:
Resolve PIVOT-634
New functionality for BeanAdapter and test files
Added:
pivot/trunk/tests/src/org/apache/pivot/tests/EnumBean.java
pivot/trunk/tests/src/org/apache/pivot/tests/EnumBeanTest.java
pivot/trunk/tests/src/org/apache/pivot/tests/enum_bean.bxml
Modified:
pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
Modified: pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java?rev=997274&r1=997273&r2=997274&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java Wed Sep 15 10:57:37 2010
@@ -21,8 +21,10 @@ import java.lang.reflect.InvocationTarge
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
+import java.util.Locale;
import java.util.NoSuchElementException;
import org.apache.pivot.collections.Map;
@@ -148,6 +150,7 @@ public class BeanAdapter implements Map<
public static final String SET_PREFIX = "set";
public static final String FIELD_PREFIX = "~";
+ private static final String ENUM_VALUE_OF_METHOD_NAME = "valueOf";
private static final String ILLEGAL_ACCESS_EXCEPTION_MESSAGE_FORMAT =
"Unable to access property \"%s\" for type %s.";
@@ -841,6 +844,8 @@ public class BeanAdapter implements Map<
if (type.isAssignableFrom(value.getClass())) {
// Value doesn't need coercion
coercedValue = value;
+ } else if (type.isEnum() && value instanceof String) {
+ coercedValue = coerceEnum(value, type);
} else {
// Coerce the value to the requested type
if (type == Boolean.class
@@ -902,4 +907,65 @@ public class BeanAdapter implements Map<
return (T)coercedValue;
}
+
+ /**
+ * Attempt to coerce a String to an instance of a supplied enum class.
+ * <p>
+ * The supplied String will be converted to upper case using
+ * <code>Locale.ENGLISH</code> before being used in an invocation of
+ * <code>T.valueOf(String)</code>.
+ * <p>
+ * Depends on the existence of a <code>public static T valueOf(String
+ * name)</code> method as defined in the <a href=
+ * "http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9"
+ * >Java Language Specification</a>.
+ *
+ * @param <T> Coercion target type.
+ * @param value String to be coerced.
+ * @param type Target enum class.
+ * @return The coerced value.
+ */
+ @SuppressWarnings("unchecked")
+ private static <T> T coerceEnum(Object value, Class<? extends T> type) {
+ if (type == null || !type.isEnum()) {
+ throw new IllegalArgumentException(String.format(
+ "Supplied Class is not an Enum. Class=%s", (type == null ? null : type.getName())));
+ }
+ if (!(value instanceof String)) {
+ throw new IllegalArgumentException(String.format(
+ "Non-null String value must be supplied for enum coercion. Value=%s",
+ (value == null ? null : value.getClass().getName())));
+ }
+
+ // Find and invoke the valueOf(String) method, with an upper case
+ // version of the supplied String
+ T coercedValue = null;
+ try {
+ Method valueOfMethod = type.getMethod(ENUM_VALUE_OF_METHOD_NAME, String.class);
+ if (valueOfMethod != null) {
+ String valueString = ((String) value).toUpperCase(Locale.ENGLISH);
+ coercedValue = (T) valueOfMethod.invoke(null, valueString);
+ }
+ }
+ // Nothing to be gained by handling the getMethod() & invoke()
+ // Exceptions separately
+ catch (IllegalAccessException e) {
+ throwCoerceEnumException(value, type, e);
+ } catch (InvocationTargetException e) {
+ throwCoerceEnumException(value, type, e);
+ } catch (SecurityException e) {
+ throwCoerceEnumException(value, type, e);
+ } catch (NoSuchMethodException e) {
+ throwCoerceEnumException(value, type, e);
+ }
+
+ return coercedValue;
+ }
+
+ private static void throwCoerceEnumException(Object value, Class<?> type, Throwable cause) {
+ String message = String.format(
+ "Unable to coerce %s (\"%s\") to %s.\nValid enum constants - %s",
+ value.getClass().getName(), value, type, Arrays.toString(type.getEnumConstants()));
+ throw new IllegalArgumentException(message, cause);
+ }
}
Added: pivot/trunk/tests/src/org/apache/pivot/tests/EnumBean.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/EnumBean.java?rev=997274&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/EnumBean.java (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/EnumBean.java Wed Sep 15 10:57:37 2010
@@ -0,0 +1,410 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.apache.pivot.tests;
+
+import org.apache.pivot.beans.BeanAdapter;
+import org.apache.pivot.util.Vote;
+import org.apache.pivot.web.Query;
+import org.apache.pivot.wtk.BindType;
+import org.apache.pivot.wtk.Button;
+import org.apache.pivot.wtk.Cursor;
+import org.apache.pivot.wtk.DropAction;
+import org.apache.pivot.wtk.FileBrowserSheet;
+import org.apache.pivot.wtk.FocusTraversalDirection;
+import org.apache.pivot.wtk.GraphicsUtilities;
+import org.apache.pivot.wtk.HorizontalAlignment;
+import org.apache.pivot.wtk.ImageView;
+import org.apache.pivot.wtk.Keyboard;
+import org.apache.pivot.wtk.ListView;
+import org.apache.pivot.wtk.MessageType;
+import org.apache.pivot.wtk.Mouse;
+import org.apache.pivot.wtk.Orientation;
+import org.apache.pivot.wtk.ScrollPane;
+import org.apache.pivot.wtk.SortDirection;
+import org.apache.pivot.wtk.SplitPane;
+import org.apache.pivot.wtk.TableView;
+import org.apache.pivot.wtk.TableViewHeader;
+import org.apache.pivot.wtk.TextArea;
+import org.apache.pivot.wtk.TextDecoration;
+import org.apache.pivot.wtk.TreeView;
+import org.apache.pivot.wtk.VerticalAlignment;
+import org.apache.pivot.wtk.media.BufferedImageSerializer;
+import org.apache.pivot.wtk.media.Picture;
+import org.apache.pivot.wtk.media.drawing.Arc;
+import org.apache.pivot.wtk.media.drawing.Path;
+import org.apache.pivot.wtk.skin.CardPaneSkin;
+import org.apache.pivot.wtk.text.BulletedList;
+import org.apache.pivot.wtk.text.NumberedList;
+
+/**
+ * Simple bean for testing String to enum coercion.
+ * {@link BeanAdapter#coerceEnum(Object, Class)}.
+ * <p>
+ * All accessors were created using Eclipse's 'Generate Getters & Setters"
+ * source generation. No addtional code has been added to them, so they
+ * can safely be deleted and regenerated if required.
+ */
+public class EnumBean {
+
+ // Public non-static field for testing BeanAdapter#get("~orientationField");
+ public Orientation orientationField;
+
+ private Arc.Type arcType;
+ private BindType bindType;
+ private BufferedImageSerializer.Format bufferedImageSerializerFormat;
+ private BulletedList.Style bulletedListStyle;
+ private Button.State buttonState;
+ private CardPaneSkin.SelectionChangeEffect selectionChangeEffect;
+ private Cursor cursor;
+ private DropAction dropAction;
+ private FileBrowserSheet.Mode fileBrowserSheetMode;
+ private FocusTraversalDirection focusTraversalDirection;
+ private GraphicsUtilities.PaintType paintType;
+ private HorizontalAlignment horizontalAlignment;
+ private ImageView.ImageBindMapping.Type imageBindMappingType;
+ private Keyboard.KeyLocation keyLocation;
+ private Keyboard.Modifier modifier;
+ private ListView.SelectMode listViewSelectMode;
+ private MessageBusTest.TestMessage testMessage;
+ private MessageType messageType;
+ private Mouse.Button mouseButton;
+ private Mouse.ScrollType mouseScrollType;
+ private NumberedList.Style numberedListStyle;
+ private Orientation orientation;
+ private Path.WindingRule windingRule;
+ private Picture.Interpolation interpolation;
+ private Query.Method queryMethod;
+ private ScrollPane.Corner.Placement placement;
+ private ScrollPane.ScrollBarPolicy scrollBarPolicy;
+ private SortDirection sortDirection;
+ private SplitPane.Region splitPaneRegion;
+ private SplitPane.ResizeMode splitPaneResizeMode;
+ private TableView.SelectMode tableViewSelectMode;
+ private TableViewHeader.SortMode sortMode;
+ private TextDecoration textDecoration;
+ private TextArea.ScrollDirection scrollDirection;
+ private TreeView.NodeCheckState nodeCheckState;
+ private TreeView.SelectMode treeViewSelectMode;
+ private VerticalAlignment verticalAlignment;
+ private Vote vote;
+
+ public Arc.Type getArcType() {
+ return arcType;
+ }
+
+ public void setArcType(Arc.Type arcType) {
+ this.arcType = arcType;
+ }
+
+ public BindType getBindType() {
+ return bindType;
+ }
+
+ public void setBindType(BindType bindType) {
+ this.bindType = bindType;
+ }
+
+ public BufferedImageSerializer.Format getBufferedImageSerializerFormat() {
+ return bufferedImageSerializerFormat;
+ }
+
+ public void setBufferedImageSerializerFormat(
+ BufferedImageSerializer.Format bufferedImageSerializerFormat) {
+ this.bufferedImageSerializerFormat = bufferedImageSerializerFormat;
+ }
+
+ public BulletedList.Style getBulletedListStyle() {
+ return bulletedListStyle;
+ }
+
+ public void setBulletedListStyle(BulletedList.Style bulletedListStyle) {
+ this.bulletedListStyle = bulletedListStyle;
+ }
+
+ public Button.State getButtonState() {
+ return buttonState;
+ }
+
+ public void setButtonState(Button.State buttonState) {
+ this.buttonState = buttonState;
+ }
+
+ public CardPaneSkin.SelectionChangeEffect getSelectionChangeEffect() {
+ return selectionChangeEffect;
+ }
+
+ public void setSelectionChangeEffect(CardPaneSkin.SelectionChangeEffect selectionChangeEffect) {
+ this.selectionChangeEffect = selectionChangeEffect;
+ }
+
+ public Cursor getCursor() {
+ return cursor;
+ }
+
+ public void setCursor(Cursor cursor) {
+ this.cursor = cursor;
+ }
+
+ public DropAction getDropAction() {
+ return dropAction;
+ }
+
+ public void setDropAction(DropAction dropAction) {
+ this.dropAction = dropAction;
+ }
+
+ public FileBrowserSheet.Mode getFileBrowserSheetMode() {
+ return fileBrowserSheetMode;
+ }
+
+ public void setFileBrowserSheetMode(FileBrowserSheet.Mode fileBrowserSheetMode) {
+ this.fileBrowserSheetMode = fileBrowserSheetMode;
+ }
+
+ public FocusTraversalDirection getFocusTraversalDirection() {
+ return focusTraversalDirection;
+ }
+
+ public void setFocusTraversalDirection(FocusTraversalDirection focusTraversalDirection) {
+ this.focusTraversalDirection = focusTraversalDirection;
+ }
+
+ public GraphicsUtilities.PaintType getPaintType() {
+ return paintType;
+ }
+
+ public void setPaintType(GraphicsUtilities.PaintType paintType) {
+ this.paintType = paintType;
+ }
+
+ public HorizontalAlignment getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+ public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) {
+ this.horizontalAlignment = horizontalAlignment;
+ }
+
+ public ImageView.ImageBindMapping.Type getImageBindMappingType() {
+ return imageBindMappingType;
+ }
+
+ public void setImageBindMappingType(ImageView.ImageBindMapping.Type imageBindMappingType) {
+ this.imageBindMappingType = imageBindMappingType;
+ }
+
+ public Keyboard.KeyLocation getKeyLocation() {
+ return keyLocation;
+ }
+
+ public void setKeyLocation(Keyboard.KeyLocation keyLocation) {
+ this.keyLocation = keyLocation;
+ }
+
+ public Keyboard.Modifier getModifier() {
+ return modifier;
+ }
+
+ public void setModifier(Keyboard.Modifier modifier) {
+ this.modifier = modifier;
+ }
+
+ public ListView.SelectMode getListViewSelectMode() {
+ return listViewSelectMode;
+ }
+
+ public void setListViewSelectMode(ListView.SelectMode listViewSelectMode) {
+ this.listViewSelectMode = listViewSelectMode;
+ }
+
+ public MessageBusTest.TestMessage getTestMessage() {
+ return testMessage;
+ }
+
+ public void setTestMessage(MessageBusTest.TestMessage testMessage) {
+ this.testMessage = testMessage;
+ }
+
+ public MessageType getMessageType() {
+ return messageType;
+ }
+
+ public void setMessageType(MessageType messageType) {
+ this.messageType = messageType;
+ }
+
+ public Mouse.Button getMouseButton() {
+ return mouseButton;
+ }
+
+ public void setMouseButton(Mouse.Button mouseButton) {
+ this.mouseButton = mouseButton;
+ }
+
+ public Mouse.ScrollType getMouseScrollType() {
+ return mouseScrollType;
+ }
+
+ public void setMouseScrollType(Mouse.ScrollType mouseScrollType) {
+ this.mouseScrollType = mouseScrollType;
+ }
+
+ public NumberedList.Style getNumberedListStyle() {
+ return numberedListStyle;
+ }
+
+ public void setNumberedListStyle(NumberedList.Style numberedListStyle) {
+ this.numberedListStyle = numberedListStyle;
+ }
+
+ public Orientation getOrientation() {
+ return orientation;
+ }
+
+ public void setOrientation(Orientation orientation) {
+ this.orientation = orientation;
+ }
+
+ public Path.WindingRule getWindingRule() {
+ return windingRule;
+ }
+
+ public void setWindingRule(Path.WindingRule windingRule) {
+ this.windingRule = windingRule;
+ }
+
+ public Picture.Interpolation getInterpolation() {
+ return interpolation;
+ }
+
+ public void setInterpolation(Picture.Interpolation interpolation) {
+ this.interpolation = interpolation;
+ }
+
+ public Query.Method getQueryMethod() {
+ return queryMethod;
+ }
+
+ public void setQueryMethod(Query.Method queryMethod) {
+ this.queryMethod = queryMethod;
+ }
+
+ public ScrollPane.Corner.Placement getPlacement() {
+ return placement;
+ }
+
+ public void setPlacement(ScrollPane.Corner.Placement placement) {
+ this.placement = placement;
+ }
+
+ public ScrollPane.ScrollBarPolicy getScrollBarPolicy() {
+ return scrollBarPolicy;
+ }
+
+ public void setScrollBarPolicy(ScrollPane.ScrollBarPolicy scrollBarPolicy) {
+ this.scrollBarPolicy = scrollBarPolicy;
+ }
+
+ public SortDirection getSortDirection() {
+ return sortDirection;
+ }
+
+ public void setSortDirection(SortDirection sortDirection) {
+ this.sortDirection = sortDirection;
+ }
+
+ public SplitPane.Region getSplitPaneRegion() {
+ return splitPaneRegion;
+ }
+
+ public void setSplitPaneRegion(SplitPane.Region splitPaneRegion) {
+ this.splitPaneRegion = splitPaneRegion;
+ }
+
+ public SplitPane.ResizeMode getSplitPaneResizeMode() {
+ return splitPaneResizeMode;
+ }
+
+ public void setSplitPaneResizeMode(SplitPane.ResizeMode splitPaneResizeMode) {
+ this.splitPaneResizeMode = splitPaneResizeMode;
+ }
+
+ public TableView.SelectMode getTableViewSelectMode() {
+ return tableViewSelectMode;
+ }
+
+ public void setTableViewSelectMode(TableView.SelectMode tableViewSelectMode) {
+ this.tableViewSelectMode = tableViewSelectMode;
+ }
+
+ public TableViewHeader.SortMode getSortMode() {
+ return sortMode;
+ }
+
+ public void setSortMode(TableViewHeader.SortMode sortMode) {
+ this.sortMode = sortMode;
+ }
+
+ public TextDecoration getTextDecoration() {
+ return textDecoration;
+ }
+
+ public void setTextDecoration(TextDecoration textDecoration) {
+ this.textDecoration = textDecoration;
+ }
+
+ public TextArea.ScrollDirection getScrollDirection() {
+ return scrollDirection;
+ }
+
+ public void setScrollDirection(TextArea.ScrollDirection scrollDirection) {
+ this.scrollDirection = scrollDirection;
+ }
+
+ public TreeView.NodeCheckState getNodeCheckState() {
+ return nodeCheckState;
+ }
+
+ public void setNodeCheckState(TreeView.NodeCheckState nodeCheckState) {
+ this.nodeCheckState = nodeCheckState;
+ }
+
+ public TreeView.SelectMode getTreeViewSelectMode() {
+ return treeViewSelectMode;
+ }
+
+ public void setTreeViewSelectMode(TreeView.SelectMode treeViewSelectMode) {
+ this.treeViewSelectMode = treeViewSelectMode;
+ }
+
+ public VerticalAlignment getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+ public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
+ this.verticalAlignment = verticalAlignment;
+ }
+
+ public Vote getVote() {
+ return vote;
+ }
+
+ public void setVote(Vote vote) {
+ this.vote = vote;
+ }
+}
Added: pivot/trunk/tests/src/org/apache/pivot/tests/EnumBeanTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/EnumBeanTest.java?rev=997274&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/EnumBeanTest.java (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/EnumBeanTest.java Wed Sep 15 10:57:37 2010
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.apache.pivot.tests;
+
+import java.io.IOException;
+
+import org.apache.pivot.beans.BXMLSerializer;
+import org.apache.pivot.beans.BeanAdapter;
+import org.apache.pivot.serialization.SerializationException;
+import org.apache.pivot.wtk.Orientation;
+
+public class EnumBeanTest {
+ public static void main(String[] args) {
+
+ BXMLSerializer bxmlSerializer = new BXMLSerializer();
+ try {
+ EnumBean enumBean = (EnumBean) bxmlSerializer.readObject(EnumBeanTest.class,
+ "enum_bean.bxml");
+ System.out.println("Bean read OK - " + enumBean);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (SerializationException e) {
+ e.printStackTrace();
+ }
+
+ // Test BeanAdapter get/put using field access prefix '~'
+ EnumBean enumBean = new EnumBean();
+ BeanAdapter ba = new BeanAdapter(enumBean);
+
+ ba.put("~orientationField", Orientation.HORIZONTAL);
+ dump(enumBean, ba);
+
+ ba.put("~orientationField", "vertical");
+ dump(enumBean, ba);
+ }
+
+ private static void dump(EnumBean enumBean, BeanAdapter ba) {
+ Object value = enumBean.orientationField;
+ System.out.println(String.format("\n%-40s %-20s %s", "Direct field access", value,
+ (value == null) ? "[null]" : value.getClass().getName()));
+
+ value = ba.get("~orientationField");
+ System.out.println(String.format("%-40s %-20s %s", "~orientationField", value,
+ (value == null) ? "[null]" : value.getClass().getName()));
+ }
+}
Added: pivot/trunk/tests/src/org/apache/pivot/tests/enum_bean.bxml
URL: http://svn.apache.org/viewvc/pivot/trunk/tests/src/org/apache/pivot/tests/enum_bean.bxml?rev=997274&view=auto
==============================================================================
--- pivot/trunk/tests/src/org/apache/pivot/tests/enum_bean.bxml (added)
+++ pivot/trunk/tests/src/org/apache/pivot/tests/enum_bean.bxml Wed Sep 15 10:57:37 2010
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you 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.
+-->
+
+<!--
+Tests the setting of bean enum properties without requiring the enum
+constant name to be specified in a case sensitive manner.
+
+There is also no requirement for the bean itself to have anything other
+than a standard setter methods. ie, No overloaded String setter method is
+required in order to handle the Enum.valueOf(String) aspect of the coercion.
+-->
+<EnumBean
+ xmlns="org.apache.pivot.tests"
+ xmlns:bxml="http://pivot.apache.org/bxml"
+
+ arcType="chord"
+ bindType="load"
+ bufferedImageSerializerFormat="png"
+ bulletedListStyle="circle"
+ buttonState="mixed"
+ cursor="crosshair"
+ dropAction="copy"
+ fileBrowserSheetMode="open"
+ focusTraversalDirection="backward"
+ horizontalAlignment="center"
+ imageBindMappingType="image"
+ interpolation="bicubic"
+ keyLocation="keypad"
+ listViewSelectMode="multi"
+ messageType="error"
+ modifier="alt"
+ mouseButton="left"
+ mouseScrollType="block"
+ nodeCheckState="checked"
+ numberedListStyle="decimal"
+ orientation="horizontal"
+ paintType="gradient"
+ placement="bottom_left"
+ queryMethod="delete"
+ scrollBarPolicy="always"
+ selectionChangeEffect="crossfade"
+ scrollDirection="down"
+ sortDirection="ascending"
+ sortMode="multi_column"
+ splitPaneRegion="bottom_right"
+ splitPaneResizeMode="primary_region"
+ tableViewSelectMode="multi"
+ testMessage="goodbye"
+ textDecoration="strikethrough"
+ treeViewSelectMode="multi"
+ verticalAlignment="bottom"
+ vote="approve">
+
+ <arcType>chord</arcType>
+ <arcType>open</arcType>
+ <arcType>pie</arcType>
+
+ <bindType>load</bindType>
+ <bindType>store</bindType>
+ <bindType>both</bindType>
+
+ <bufferedImageSerializerFormat>png</bufferedImageSerializerFormat>
+ <bufferedImageSerializerFormat>jpeg</bufferedImageSerializerFormat>
+ <bufferedImageSerializerFormat>bmp</bufferedImageSerializerFormat>
+ <bufferedImageSerializerFormat>wbmp</bufferedImageSerializerFormat>
+ <bufferedImageSerializerFormat>gif</bufferedImageSerializerFormat>
+
+ <bulletedListStyle>circle</bulletedListStyle>
+ <bulletedListStyle>circle_outline</bulletedListStyle>
+
+ <buttonState>mixed</buttonState>
+ <buttonState>selected</buttonState>
+ <buttonState>unselected</buttonState>
+
+ <cursor>crosshair</cursor>
+ <cursor>default</cursor>
+ <cursor>hand</cursor>
+ <cursor>move</cursor>
+ <cursor>resize_east</cursor>
+ <cursor>resize_north</cursor>
+ <cursor>resize_north_east</cursor>
+ <cursor>resize_north_west</cursor>
+ <cursor>resize_south</cursor>
+ <cursor>resize_south_east</cursor>
+ <cursor>resize_south_west</cursor>
+ <cursor>resize_west</cursor>
+ <cursor>text</cursor>
+ <cursor>wait</cursor>
+
+ <dropAction>copy</dropAction>
+ <dropAction>link</dropAction>
+ <dropAction>move</dropAction>
+
+ <fileBrowserSheetMode>open</fileBrowserSheetMode>
+ <fileBrowserSheetMode>open_multiple</fileBrowserSheetMode>
+ <fileBrowserSheetMode>save_as</fileBrowserSheetMode>
+ <fileBrowserSheetMode>save_to</fileBrowserSheetMode>
+
+ <focusTraversalDirection>backward</focusTraversalDirection>
+ <focusTraversalDirection>forward</focusTraversalDirection>
+
+ <horizontalAlignment>center</horizontalAlignment>
+ <horizontalAlignment>left</horizontalAlignment>
+ <horizontalAlignment>right</horizontalAlignment>
+
+ <imageBindMappingType>image</imageBindMappingType>
+ <imageBindMappingType>name</imageBindMappingType>
+ <imageBindMappingType>url</imageBindMappingType>
+
+ <interpolation>bicubic</interpolation>
+ <interpolation>bilinear</interpolation>
+ <interpolation>nearest_neighbor</interpolation>
+
+ <keyLocation>keypad</keyLocation>
+ <keyLocation>left</keyLocation>
+ <keyLocation>right</keyLocation>
+ <keyLocation>standard</keyLocation>
+
+ <listViewSelectMode>multi</listViewSelectMode>
+ <listViewSelectMode>none</listViewSelectMode>
+ <listViewSelectMode>single</listViewSelectMode>
+
+ <messageType>error</messageType>
+ <messageType>info</messageType>
+ <messageType>question</messageType>
+ <messageType>warning</messageType>
+
+ <modifier>alt</modifier>
+ <modifier>ctrl</modifier>
+ <modifier>meta</modifier>
+ <modifier>shift</modifier>
+
+ <mouseButton>left</mouseButton>
+ <mouseButton>middle</mouseButton>
+ <mouseButton>right</mouseButton>
+
+ <mouseScrollType>block</mouseScrollType>
+ <mouseScrollType>unit</mouseScrollType>
+
+ <nodeCheckState>checked</nodeCheckState>
+ <nodeCheckState>mixed</nodeCheckState>
+ <nodeCheckState>unchecked</nodeCheckState>
+
+ <numberedListStyle>decimal</numberedListStyle>
+ <numberedListStyle>lower_alpha</numberedListStyle>
+ <numberedListStyle>upper_alpha</numberedListStyle>
+ <numberedListStyle>lower_roman</numberedListStyle>
+ <numberedListStyle>upper_roman</numberedListStyle>
+
+ <orientation>horizontal</orientation>
+ <orientation>vertical</orientation>
+
+ <paintType>gradient</paintType>
+ <paintType>linear_gradient</paintType>
+ <paintType>radial_gradient</paintType>
+ <paintType>solid_color</paintType>
+
+ <placement>bottom_left</placement>
+ <placement>bottom_right</placement>
+ <placement>top_left</placement>
+ <placement>top_right</placement>
+
+ <queryMethod>delete</queryMethod>
+ <queryMethod>get</queryMethod>
+ <queryMethod>post</queryMethod>
+ <queryMethod>put</queryMethod>
+
+ <scrollBarPolicy>always</scrollBarPolicy>
+ <scrollBarPolicy>auto</scrollBarPolicy>
+ <scrollBarPolicy>fill</scrollBarPolicy>
+ <scrollBarPolicy>fill_to_capacity</scrollBarPolicy>
+ <scrollBarPolicy>never</scrollBarPolicy>
+
+ <selectionChangeEffect>crossfade</selectionChangeEffect>
+ <selectionChangeEffect>horizontal_flip</selectionChangeEffect>
+ <selectionChangeEffect>horizontal_slide</selectionChangeEffect>
+ <selectionChangeEffect>vertical_flip</selectionChangeEffect>
+ <selectionChangeEffect>vertical_slide</selectionChangeEffect>
+ <selectionChangeEffect>zoom</selectionChangeEffect>
+
+ <scrollDirection>down</scrollDirection>
+ <scrollDirection>up</scrollDirection>
+
+ <sortDirection>ascending</sortDirection>
+ <sortDirection>descending</sortDirection>
+
+ <sortMode>multi_column</sortMode>
+ <sortMode>none</sortMode>
+ <sortMode>single_column</sortMode>
+
+ <splitPaneRegion>bottom_right</splitPaneRegion>
+ <splitPaneRegion>top_left</splitPaneRegion>
+
+ <splitPaneResizeMode>primary_region</splitPaneResizeMode>
+ <splitPaneResizeMode>split_ratio</splitPaneResizeMode>
+
+ <tableViewSelectMode>multi</tableViewSelectMode>
+ <tableViewSelectMode>none</tableViewSelectMode>
+ <tableViewSelectMode>single</tableViewSelectMode>
+
+ <testMessage>goodbye</testMessage>
+ <testMessage>hello</testMessage>
+
+ <textDecoration>strikethrough</textDecoration>
+ <textDecoration>underline</textDecoration>
+
+ <treeViewSelectMode>multi</treeViewSelectMode>
+ <treeViewSelectMode>none</treeViewSelectMode>
+ <treeViewSelectMode>single</treeViewSelectMode>
+
+ <verticalAlignment>bottom</verticalAlignment>
+ <verticalAlignment>center</verticalAlignment>
+ <verticalAlignment>top</verticalAlignment>
+
+ <vote>approve</vote>
+ <vote>defer</vote>
+ <vote>deny</vote>
+
+ <windingRule>even_odd</windingRule>
+ <windingRule>non_zero</windingRule>
+
+</EnumBean>
\ No newline at end of file
Re: svn commit: r997274 - in /pivot/trunk: core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Chris Bartlett <cb...@gmail.com>.
Changes made in r997330
On 15 September 2010 19:35, Greg Brown <gk...@mac.com> wrote:
> >>> + private static <T> T coerceEnum(Object value, Class<? extends T>
> type) {
> >>
> >> Was there a reason you put this in a separate method? I imagined we'd
> just
> >> inline it in the coerce method.
> >>
> > I was thinking it might be useful in its own right & the logic is
> different
> > enough from the primitives coercion.
>
> Since the same functionality is available by calling coerce() directly, I
> think it would be best to simply inline it there.
>
>
>
Re: svn commit: r997274 - in /pivot/trunk:
core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java
tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Greg Brown <gk...@mac.com>.
>>> + private static <T> T coerceEnum(Object value, Class<? extends T> type) {
>>
>> Was there a reason you put this in a separate method? I imagined we'd just
>> inline it in the coerce method.
>>
> I was thinking it might be useful in its own right & the logic is different
> enough from the primitives coercion.
Since the same functionality is available by calling coerce() directly, I think it would be best to simply inline it there.
Re: svn commit: r997274 - in /pivot/trunk:
core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java
tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Greg Brown <gk...@mac.com>.
> One other thing I was wondering about is whether I should have deprecated
> the setXXX(String) methods that I removed.
If we made this change between 1.5 and a hypothetical 1.6 release, it might make sense to deprecate them. However, since we're moving to 2.0, I think it is OK to simply remove them (we expect to see major API changes across major releases).
Re: svn commit: r997274 - in /pivot/trunk: core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Chris Bartlett <cb...@gmail.com>.
One other thing I was wondering about is whether I should have deprecated
the setXXX(String) methods that I removed.
I've noticed past API changes that might have deprecated methods but didn't
(generally renaming methods).
Obviously it would be less imposing on users to keep the deprecated methods
for at least a single release.
I can back out the change & deprecate the methods if preferred.
Chris
On 15 September 2010 19:14, Chris Bartlett <cb...@gmail.com> wrote:
> Greg,
>
> Replies below
>
> Chris
>
> On 15 September 2010 18:38, Greg Brown <gk...@mac.com> wrote:
>
>> Hi Chris,
>>
>> Looks good - thanks for tackling this one. Comments below:
>>
>> > Modified: pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
>> > @@ -841,6 +844,8 @@ public class BeanAdapter implements Map<
>> > if (type.isAssignableFrom(value.getClass())) {
>> > // Value doesn't need coercion
>> > coercedValue = value;
>> > + } else if (type.isEnum() && value instanceof String) {
>> > + coercedValue = coerceEnum(value, type);
>>
>> Since this is a coercion method, it might be more flexible to check for
>> value != null and call toString() on it.
>>
>> OK, will do.
>
> > + @SuppressWarnings("unchecked")
>> > + private static <T> T coerceEnum(Object value, Class<? extends T>
>> type) {
>>
>> Was there a reason you put this in a separate method? I imagined we'd just
>> inline it in the coerce method.
>>
> I was thinking it might be useful in its own right & the logic is different
> enough from the primitives coercion.
> If you'd rather have it inline, I can make the change.
>
>
>> > + }
>> > + if (!(value instanceof String)) {
>> > + throw new IllegalArgumentException(String.format(
>> > + "Non-null String value must be supplied for enum
>> coercion. Value=%s",
>> > + (value == null ? null : value.getClass().getName())));
>> > + }
>>
>> Same comment here as above - it would probably be more flexible to call
>> toString() rather than cast to String. Also, null is a valid enum value, so
>> we should allow it.
>>
>> Will make the change.
>
>
>> > +
>> > + // Find and invoke the valueOf(String) method, with an upper
>> case
>> > + // version of the supplied String
>> > + T coercedValue = null;
>> > + try {
>> > + Method valueOfMethod =
>> type.getMethod(ENUM_VALUE_OF_METHOD_NAME, String.class);
>> > + if (valueOfMethod != null) {
>> > + String valueString = ((String)
>> value).toUpperCase(Locale.ENGLISH);
>> > + coercedValue = (T) valueOfMethod.invoke(null,
>> valueString);
>> > + }
>> > + }
>> > + // Nothing to be gained by handling the getMethod() & invoke()
>> > + // Exceptions separately
>> > + catch (IllegalAccessException e) {
>> > + throwCoerceEnumException(value, type, e);
>>
>> In general, we don't define "thrower" methods. You could instead define a
>> constant for your exception message and re-use that in each catch block.
>> Later, when we (hopefully) get multi-catch in JDK 7, we can consolidate
>> blocks like this.
>>
>> Just trying to reduce code repetition, but I know it is clunky.
> I should have removed it earlier actually, as I simplified the exception
> message so it can just as easily be created using a constant as you
> suggested. I blame delays between writing, testing and checking in for not
> catching it. :)
>
>
>
Re: svn commit: r997274 - in /pivot/trunk: core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Chris Bartlett <cb...@gmail.com>.
Greg,
Replies below
Chris
On 15 September 2010 18:38, Greg Brown <gk...@mac.com> wrote:
> Hi Chris,
>
> Looks good - thanks for tackling this one. Comments below:
>
> > Modified: pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
> > @@ -841,6 +844,8 @@ public class BeanAdapter implements Map<
> > if (type.isAssignableFrom(value.getClass())) {
> > // Value doesn't need coercion
> > coercedValue = value;
> > + } else if (type.isEnum() && value instanceof String) {
> > + coercedValue = coerceEnum(value, type);
>
> Since this is a coercion method, it might be more flexible to check for
> value != null and call toString() on it.
>
> OK, will do.
> + @SuppressWarnings("unchecked")
> > + private static <T> T coerceEnum(Object value, Class<? extends T>
> type) {
>
> Was there a reason you put this in a separate method? I imagined we'd just
> inline it in the coerce method.
>
I was thinking it might be useful in its own right & the logic is different
enough from the primitives coercion.
If you'd rather have it inline, I can make the change.
> > + }
> > + if (!(value instanceof String)) {
> > + throw new IllegalArgumentException(String.format(
> > + "Non-null String value must be supplied for enum
> coercion. Value=%s",
> > + (value == null ? null : value.getClass().getName())));
> > + }
>
> Same comment here as above - it would probably be more flexible to call
> toString() rather than cast to String. Also, null is a valid enum value, so
> we should allow it.
>
> Will make the change.
> > +
> > + // Find and invoke the valueOf(String) method, with an upper
> case
> > + // version of the supplied String
> > + T coercedValue = null;
> > + try {
> > + Method valueOfMethod =
> type.getMethod(ENUM_VALUE_OF_METHOD_NAME, String.class);
> > + if (valueOfMethod != null) {
> > + String valueString = ((String)
> value).toUpperCase(Locale.ENGLISH);
> > + coercedValue = (T) valueOfMethod.invoke(null,
> valueString);
> > + }
> > + }
> > + // Nothing to be gained by handling the getMethod() & invoke()
> > + // Exceptions separately
> > + catch (IllegalAccessException e) {
> > + throwCoerceEnumException(value, type, e);
>
> In general, we don't define "thrower" methods. You could instead define a
> constant for your exception message and re-use that in each catch block.
> Later, when we (hopefully) get multi-catch in JDK 7, we can consolidate
> blocks like this.
>
> Just trying to reduce code repetition, but I know it is clunky.
I should have removed it earlier actually, as I simplified the exception
message so it can just as easily be created using a constant as you
suggested. I blame delays between writing, testing and checking in for not
catching it. :)
Re: svn commit: r997274 - in /pivot/trunk:
core/src/org/apache/pivot/beans/BeanAdapter.java
tests/src/org/apache/pivot/tests/EnumBean.java
tests/src/org/apache/pivot/tests/EnumBeanTest.java
tests/src/org/apache/pivot/tests/enum_bean.bxml
Posted by Greg Brown <gk...@mac.com>.
Hi Chris,
Looks good - thanks for tackling this one. Comments below:
> Modified: pivot/trunk/core/src/org/apache/pivot/beans/BeanAdapter.java
> @@ -841,6 +844,8 @@ public class BeanAdapter implements Map<
> if (type.isAssignableFrom(value.getClass())) {
> // Value doesn't need coercion
> coercedValue = value;
> + } else if (type.isEnum() && value instanceof String) {
> + coercedValue = coerceEnum(value, type);
Since this is a coercion method, it might be more flexible to check for value != null and call toString() on it.
> + @SuppressWarnings("unchecked")
> + private static <T> T coerceEnum(Object value, Class<? extends T> type) {
Was there a reason you put this in a separate method? I imagined we'd just inline it in the coerce method.
> + }
> + if (!(value instanceof String)) {
> + throw new IllegalArgumentException(String.format(
> + "Non-null String value must be supplied for enum coercion. Value=%s",
> + (value == null ? null : value.getClass().getName())));
> + }
Same comment here as above - it would probably be more flexible to call toString() rather than cast to String. Also, null is a valid enum value, so we should allow it.
> +
> + // Find and invoke the valueOf(String) method, with an upper case
> + // version of the supplied String
> + T coercedValue = null;
> + try {
> + Method valueOfMethod = type.getMethod(ENUM_VALUE_OF_METHOD_NAME, String.class);
> + if (valueOfMethod != null) {
> + String valueString = ((String) value).toUpperCase(Locale.ENGLISH);
> + coercedValue = (T) valueOfMethod.invoke(null, valueString);
> + }
> + }
> + // Nothing to be gained by handling the getMethod() & invoke()
> + // Exceptions separately
> + catch (IllegalAccessException e) {
> + throwCoerceEnumException(value, type, e);
In general, we don't define "thrower" methods. You could instead define a constant for your exception message and re-use that in each catch block. Later, when we (hopefully) get multi-catch in JDK 7, we can consolidate blocks like this.
Greg