You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/05/06 23:24:54 UTC
svn commit: r772431 - in /incubator/pivot/trunk:
tutorials/src/pivot/tutorials/ tutorials/src/pivot/tutorials/drawing/
tutorials/src/pivot/tutorials/stocktracker/
wtk/src/pivot/wtk/media/drawing/ wtk/src/pivot/wtkx/
Author: gbrown
Date: Wed May 6 21:24:48 2009
New Revision: 772431
URL: http://svn.apache.org/viewvc?rev=772431&view=rev
Log:
Add resource/locale support to WTKX binding; ensure that runtime binding binds to entire class hierarchy.
Modified:
incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java
incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/StockTracker.java
incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/stocktracker.wtkx
incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java
incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/Demo.java Wed May 6 21:24:48 2009
@@ -140,20 +140,20 @@
private Window window = null;
- @Load("demo.wtkx") private Component content;
- @Bind(resource="content") private Rollup buttonsRollup;
- @Bind(resource="content") private Rollup listsRollup;
- @Bind(resource="content") private Rollup textRollup;
- @Bind(resource="content") private Rollup calendarsRollup;
- @Bind(resource="content") private Rollup navigationRollup;
- @Bind(resource="content") private Rollup splittersRollup;
- @Bind(resource="content") private Rollup menusRollup;
- @Bind(resource="content") private Rollup metersRollup;
- @Bind(resource="content") private Rollup spinnersRollup;
- @Bind(resource="content") private Rollup tablesRollup;
- @Bind(resource="content") private Rollup treesRollup;
- @Bind(resource="content") private Rollup dragDropRollup;
- @Bind(resource="content") private Rollup alertsRollup;
+ @Load(name="demo.wtkx") private Component content;
+ @Bind(property="content") private Rollup buttonsRollup;
+ @Bind(property="content") private Rollup listsRollup;
+ @Bind(property="content") private Rollup textRollup;
+ @Bind(property="content") private Rollup calendarsRollup;
+ @Bind(property="content") private Rollup navigationRollup;
+ @Bind(property="content") private Rollup splittersRollup;
+ @Bind(property="content") private Rollup menusRollup;
+ @Bind(property="content") private Rollup metersRollup;
+ @Bind(property="content") private Rollup spinnersRollup;
+ @Bind(property="content") private Rollup tablesRollup;
+ @Bind(property="content") private Rollup treesRollup;
+ @Bind(property="content") private Rollup dragDropRollup;
+ @Bind(property="content") private Rollup alertsRollup;
public static void main(String[] args) {
DesktopApplicationContext.main(Demo.class, args);
Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/drawing/RotateLine.java Wed May 6 21:24:48 2009
@@ -28,8 +28,8 @@
import pivot.wtkx.Bindable;
public class RotateLine extends Bindable implements Application {
- @Load("rotate_line.wtkd") private Drawing drawing;
- @Bind(resource="drawing") private Shape.Rotate rotation;
+ @Load(name="rotate_line.wtkd") private Drawing drawing;
+ @Bind(property="drawing") private Shape.Rotate rotation;
private Window window = null;
Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/StockTracker.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/StockTracker.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/StockTracker.java (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/StockTracker.java Wed May 6 21:24:48 2009
@@ -28,7 +28,6 @@
import pivot.collections.List;
import pivot.collections.Sequence;
import pivot.serialization.CSVSerializer;
-import pivot.util.Resources;
import pivot.util.concurrent.Task;
import pivot.util.concurrent.TaskListener;
import pivot.web.GetQuery;
@@ -52,23 +51,25 @@
import pivot.wtk.TextInputTextListener;
import pivot.wtk.Window;
import pivot.wtk.text.TextNode;
-import pivot.wtkx.WTKXSerializer;
-
-public class StockTracker implements Application {
- private Locale locale = null;
- private Resources resources = null;
+import pivot.wtkx.Bindable;
+public class StockTracker extends Bindable implements Application {
private ArrayList<String> symbols = new ArrayList<String>();
- private Window window = null;
- private TableView stocksTableView = null;
- private TextInput symbolTextInput = null;
- private Button addSymbolButton = null;
- private Button removeSymbolsButton = null;
- private Label lastUpdateLabel = null;
- private Button yahooFinanceButton = null;
- private Container detailRootPane = null;
- private Label detailChangeLabel = null;
+ @Load(name="stocktracker.wtkx") private Window window;
+
+ @Bind(property="window") private TableView stocksTableView;
+ @Bind(property="window") private TextInput symbolTextInput;
+ @Bind(property="window") private Button addSymbolButton;
+ @Bind(property="window") private Button removeSymbolsButton;
+ @Bind(property="window") private Label lastUpdateLabel;
+ @Bind(property="window") private Button yahooFinanceButton;
+
+ @Bind(property="window", id="detail.rootPane")
+ private Container detailRootPane;
+
+ @Bind(property="window", id="detail.changeLabel")
+ private Label detailChangeLabel;
private GetQuery getQuery = null;
@@ -98,16 +99,14 @@
throws Exception {
// Set the locale
String language = properties.get(LANGUAGE_PROPERTY_NAME);
- locale = (language == null) ? Locale.getDefault() : new Locale(language);
- resources = new Resources(getClass().getName(), locale, "UTF8");
+ if (language != null) {
+ Locale.setDefault(new Locale(language));
+ }
- // Load the application's UI
- WTKXSerializer wtkxSerializer = new WTKXSerializer(resources);
- Component content =
- (Component)wtkxSerializer.readObject("pivot/tutorials/stocktracker/stocktracker.wtkx");
+ // Bind to the WTKX source
+ bind();
// Wire up event handlers
- stocksTableView = (TableView)wtkxSerializer.getObjectByName("stocksTableView");
stocksTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener() {
public void selectedRangeAdded(TableView tableView, int rangeStart, int rangeEnd) {
// No-op
@@ -140,7 +139,6 @@
}
});
- symbolTextInput = (TextInput)wtkxSerializer.getObjectByName("symbolTextInput");
symbolTextInput.getTextInputTextListeners().add(new TextInputTextListener() {
public void textChanged(TextInput textInput) {
TextNode textNode = textInput.getTextNode();
@@ -166,23 +164,18 @@
}
});
- addSymbolButton = (Button)wtkxSerializer.getObjectByName("addSymbolButton");
addSymbolButton.getButtonPressListeners().add(new ButtonPressListener() {
public void buttonPressed(Button button) {
addSymbol();
}
});
- removeSymbolsButton = (Button)wtkxSerializer.getObjectByName("removeSymbolsButton");
removeSymbolsButton.getButtonPressListeners().add(new ButtonPressListener() {
public void buttonPressed(Button button) {
removeSelectedSymbols();
}
});
- lastUpdateLabel = (Label)wtkxSerializer.getObjectByName("lastUpdateLabel");
-
- yahooFinanceButton = (Button)wtkxSerializer.getObjectByName("yahooFinanceButton");
yahooFinanceButton.getButtonPressListeners().add(new ButtonPressListener() {
public void buttonPressed(Button button) {
try {
@@ -192,14 +185,6 @@
}
});
- detailRootPane = (Container)wtkxSerializer.getObjectByName("detail.rootPane");
-
- detailChangeLabel = (Label)wtkxSerializer.getObjectByName("detail.changeLabel");
-
- window = new Window();
- window.setTitle((String)resources.get("stockTracker"));
- window.setContent(content);
- window.setMaximized(true);
window.open(display);
refreshTable();
@@ -280,10 +265,8 @@
}
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
- DateFormat.MEDIUM, locale);
- String lastUpdateText = resources.get("lastUpdate")
- + ": " + dateFormat.format(new Date());
- lastUpdateLabel.setText(lastUpdateText);
+ DateFormat.MEDIUM, Locale.getDefault());
+ lastUpdateLabel.setText(dateFormat.format(new Date()));
getQuery = null;
}
Modified: incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/stocktracker.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/stocktracker.wtkx?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/stocktracker.wtkx (original)
+++ incubator/pivot/trunk/tutorials/src/pivot/tutorials/stocktracker/stocktracker.wtkx Wed May 6 21:24:48 2009
@@ -16,92 +16,98 @@
limitations under the License.
-->
-<TablePane styles="{padding:8, horizontalSpacing:6, verticalSpacing:6}"
+<Window title="%stockTracker" maximized="true"
xmlns:wtkx="http://incubator.apache.org/pivot/wtkx/1.1"
xmlns:content="pivot.wtk.content"
xmlns:stocktracker="pivot.tutorials.stocktracker"
xmlns="pivot.wtk">
- <columns>
- <TablePane.Column width="244" />
- <TablePane.Column width="1*" />
- </columns>
-
- <rows>
- <TablePane.Row height="-1">
- <Label text="%stockTracker"
- styles="{fontBold:true, fontSize:14, verticalAlignment:'center'}" />
- </TablePane.Row>
-
- <TablePane.Row height="1*">
- <Border styles="{padding:0, color:10}">
- <content>
- <ScrollPane horizontalScrollBarPolicy="fillToCapacity"
- verticalScrollBarPolicy="fillToCapacity">
- <view>
- <TableView wtkx:id="stocksTableView" selectMode="multi"
- styles="{showHorizontalGridLines:false}">
- <columns>
- <TableView.Column name="symbol"
- headerData="%symbol" width="80" />
- <TableView.Column name="value" headerData="%value" width="80">
- <cellRenderer>
- <content:TableViewNumberCellRenderer styles="{horizontalAlignment:'right'}"
- numberFormat="$$0.00"/>
- </cellRenderer>
- </TableView.Column>
- <TableView.Column name="change" headerData="%change" width="80">
- <cellRenderer>
- <stocktracker:ChangeCellRenderer styles="{horizontalAlignment:'right'}"
- numberFormat="+0.00;-0.00"/>
- </cellRenderer>
- </TableView.Column>
- </columns>
- </TableView>
- </view>
-
- <columnHeader>
- <TableViewHeader tableView="$stocksTableView" styles="{headersPressable:false}"/>
- </columnHeader>
- </ScrollPane>
- </content>
- </Border>
-
- <Border styles="{padding:6, color:10}">
- <content>
- <wtkx:include namespace="detail" src="stocktracker.detail.wtkx" />
- </content>
- </Border>
- </TablePane.Row>
-
- <TablePane.Row height="-1">
- <FlowPane
- styles="{horizontalAlignment:'left', verticalAlignment:'center'}">
- <Label text="%symbol" styles="{fontBold:true}" />
- <TextInput wtkx:id="symbolTextInput" textSize="10"
- maximumLength="8" />
- <LinkButton wtkx:id="addSymbolButton" enabled="false"
- tooltipText="%addSymbol">
- <buttonData>
- <content:ButtonData icon="@add.png" />
- </buttonData>
- </LinkButton>
- <LinkButton wtkx:id="removeSymbolsButton" enabled="false"
- tooltipText="%removeSymbol">
- <buttonData>
- <content:ButtonData icon="@delete.png" />
- </buttonData>
- </LinkButton>
- </FlowPane>
- </TablePane.Row>
-
- <TablePane.Row height="-1">
- <Label wtkx:id="lastUpdateLabel"
- styles="{fontItalic:true, fontSize:10}" />
- <FlowPane styles="{horizontalAlignment:'right'}">
- <Label text="%dataProvidedBy" />
- <LinkButton wtkx:id="yahooFinanceButton"
- buttonData="%yahooFinance" />
- </FlowPane>
- </TablePane.Row>
- </rows>
-</TablePane>
+ <content>
+ <TablePane styles="{padding:8, horizontalSpacing:6, verticalSpacing:6}">
+ <columns>
+ <TablePane.Column width="244" />
+ <TablePane.Column width="1*" />
+ </columns>
+
+ <rows>
+ <TablePane.Row height="-1">
+ <Label text="%stockTracker"
+ styles="{fontBold:true, fontSize:14, verticalAlignment:'center'}" />
+ </TablePane.Row>
+
+ <TablePane.Row height="1*">
+ <Border styles="{padding:0, color:10}">
+ <content>
+ <ScrollPane horizontalScrollBarPolicy="fillToCapacity"
+ verticalScrollBarPolicy="fillToCapacity">
+ <view>
+ <TableView wtkx:id="stocksTableView" selectMode="multi"
+ styles="{showHorizontalGridLines:false}">
+ <columns>
+ <TableView.Column name="symbol"
+ headerData="%symbol" width="80" />
+ <TableView.Column name="value" headerData="%value" width="80">
+ <cellRenderer>
+ <content:TableViewNumberCellRenderer styles="{horizontalAlignment:'right'}"
+ numberFormat="$$0.00"/>
+ </cellRenderer>
+ </TableView.Column>
+ <TableView.Column name="change" headerData="%change" width="80">
+ <cellRenderer>
+ <stocktracker:ChangeCellRenderer styles="{horizontalAlignment:'right'}"
+ numberFormat="+0.00;-0.00"/>
+ </cellRenderer>
+ </TableView.Column>
+ </columns>
+ </TableView>
+ </view>
+
+ <columnHeader>
+ <TableViewHeader tableView="$stocksTableView" styles="{headersPressable:false}"/>
+ </columnHeader>
+ </ScrollPane>
+ </content>
+ </Border>
+
+ <Border styles="{padding:6, color:10}">
+ <content>
+ <wtkx:include namespace="detail" src="stocktracker.detail.wtkx" />
+ </content>
+ </Border>
+ </TablePane.Row>
+
+ <TablePane.Row height="-1">
+ <FlowPane
+ styles="{horizontalAlignment:'left', verticalAlignment:'center'}">
+ <Label text="%symbol" styles="{fontBold:true}" />
+ <TextInput wtkx:id="symbolTextInput" textSize="10"
+ maximumLength="8" />
+ <LinkButton wtkx:id="addSymbolButton" enabled="false"
+ tooltipText="%addSymbol">
+ <buttonData>
+ <content:ButtonData icon="@add.png" />
+ </buttonData>
+ </LinkButton>
+ <LinkButton wtkx:id="removeSymbolsButton" enabled="false"
+ tooltipText="%removeSymbol">
+ <buttonData>
+ <content:ButtonData icon="@delete.png" />
+ </buttonData>
+ </LinkButton>
+ </FlowPane>
+ </TablePane.Row>
+
+ <TablePane.Row height="-1">
+ <FlowPane>
+ <Label text="%lastUpdate"/>
+ <Label wtkx:id="lastUpdateLabel"/>
+ </FlowPane>
+ <FlowPane styles="{horizontalAlignment:'right'}">
+ <Label text="%dataProvidedBy" />
+ <LinkButton wtkx:id="yahooFinanceButton"
+ buttonData="%yahooFinance" />
+ </FlowPane>
+ </TablePane.Row>
+ </rows>
+ </TablePane>
+ </content>
+</Window>
Modified: incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtk/media/drawing/Group.java Wed May 6 21:24:48 2009
@@ -16,11 +16,8 @@
*/
package pivot.wtk.media.drawing;
-import java.awt.BasicStroke;
-import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
-import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import pivot.collections.ArrayList;
import pivot.collections.Sequence;
@@ -91,10 +88,12 @@
}
// Draw a debug rectangle
+ /*
graphics.setColor(Color.DARK_GRAY);
graphics.setStroke(new BasicStroke(0));
Bounds bounds = getBounds();
graphics.draw(new Rectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height));
+ */
}
@Override
Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/BindProcessor.java Wed May 6 21:24:48 2009
@@ -111,13 +111,13 @@
if (DEBUG) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
- String.format("Processing load(%s, %s#%s)", loadAnnotation.value(),
+ String.format("Processing load(%s, %s#%s)", loadAnnotation.name(),
tree.name.toString(), loadFieldName));
}
// Load the WTKX resource
sourceCode.append("wtkxSerializer = new pivot.wtkx.WTKXSerializer();");
- sourceCode.append(String.format("java.net.URL location = getClass().getResource(\"%s\");", loadAnnotation.value()));
+ sourceCode.append(String.format("java.net.URL location = getClass().getResource(\"%s\");", loadAnnotation.name()));
sourceCode.append("try {");
sourceCode.append("value = wtkxSerializer.readObject(location);");
sourceCode.append("} catch (Exception ex) {");
@@ -142,7 +142,7 @@
if (DEBUG) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
- String.format("Processing bind(%s.%s, %s#%s)", bindAnnotation.resource(),
+ String.format("Processing bind(%s.%s, %s#%s)", bindAnnotation.property(),
bindID, tree.name.toString(), bindFieldName));
}
@@ -224,8 +224,8 @@
BindScope bindScope = bindScopeStack.peek();
if (bindScope.loadGroups != null
- && bindScope.loadGroups.containsKey(bindAnnotation.resource())) {
- BindScope.LoadGroup loadGroup = bindScope.loadGroups.get(bindAnnotation.resource());
+ && bindScope.loadGroups.containsKey(bindAnnotation.property())) {
+ BindScope.LoadGroup loadGroup = bindScope.loadGroups.get(bindAnnotation.property());
if (loadGroup.bindFields == null) {
loadGroup.bindFields = new ArrayList<JCTree.JCVariableDecl>();
@@ -235,7 +235,7 @@
bindTally++;
} else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
- "Resource not found: " + bindAnnotation.resource(), element);
+ "Resource not found: " + bindAnnotation.property(), element);
}
}
}
Modified: incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java?rev=772431&r1=772430&r2=772431&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java (original)
+++ incubator/pivot/trunk/wtk/src/pivot/wtkx/Bindable.java Wed May 6 21:24:48 2009
@@ -22,10 +22,15 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.net.URL;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import pivot.collections.ArrayList;
import pivot.collections.HashMap;
import pivot.serialization.SerializationException;
+import pivot.util.Resources;
/**
* Base class for objects that wish to leverage WTKX binding annotations.
@@ -41,7 +46,9 @@
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
protected static @interface Load {
- public String value();
+ public String name();
+ public String resources() default "\0";
+ public String locale() default "\0";
}
/**
@@ -52,7 +59,7 @@
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
protected static @interface Bind {
- public String resource();
+ public String property();
public String id() default "\0";
}
@@ -60,88 +67,137 @@
* Applies WTKX binding annotations to this bindable object.
*/
protected void bind() throws IOException, BindException {
- // Maps resource field name to the serializer that loaded the resource
- HashMap<String, WTKXSerializer> wtkxSerializers = new HashMap<String, WTKXSerializer>();
-
- // Walk field lists and resolve WTKX annotations
+ // Walk fields and resolve annotations
+ ArrayList<Class<?>> typeHierarchy = new ArrayList<Class<?>>();
Class<?> type = getClass();
- Field[] fields = type.getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- Load loadAnnotation = field.getAnnotation(Load.class);
+ while (type != Bindable.class) {
+ typeHierarchy.add(type);
+ type = type.getSuperclass();
+ }
+
+ for (int i = typeHierarchy.getLength() - 1; i >= 0; i--) {
+ // Maps resource field name to the serializer that loaded the
+ // resource; we create it here so each subclass gets its own scope
+ HashMap<String, WTKXSerializer> wtkxSerializers = new HashMap<String, WTKXSerializer>();
- if (loadAnnotation != null) {
- // Create a serializer for the resource
+ type = typeHierarchy.get(i);
+ Field[] fields = type.getDeclaredFields();
+
+ for (int j = 0, n = fields.length; j < n; j++) {
+ Field field = fields[j];
String fieldName = field.getName();
- assert(!wtkxSerializers.containsKey(fieldName));
+ int fieldModifiers = field.getModifiers();
- WTKXSerializer wtkxSerializer = new WTKXSerializer();
- wtkxSerializers.put(fieldName, wtkxSerializer);
+ Load loadAnnotation = field.getAnnotation(Load.class);
+ if (loadAnnotation != null) {
+ // Ensure that we can write to the field
+ if ((fieldModifiers & Modifier.FINAL) > 0) {
+ throw new BindException(fieldName + " is final.");
+ }
- // Load the resource
- URL location = type.getResource(loadAnnotation.value());
- Object resource;
- try {
- resource = wtkxSerializer.readObject(location);
- } catch (SerializationException exception) {
- throw new BindException(exception);
- }
+ if ((fieldModifiers & Modifier.PUBLIC) == 0) {
+ try {
+ field.setAccessible(true);
+ } catch(SecurityException exception) {
+ throw new BindException(fieldName + " is not accessible.");
+ }
+ }
+
+ assert(!wtkxSerializers.containsKey(fieldName));
- // Set the resource into the field
- if (!field.isAccessible()) {
+ // Get the name of the resource file to use
+ Resources resources = null;
+ boolean defaultResources = false;
+
+ String baseName = loadAnnotation.resources();
+ if (baseName.equals("\0")) {
+ baseName = type.getName();
+ defaultResources = true;
+ }
+
+ // Get the resource locale
+ Locale locale;
+ String language = loadAnnotation.locale();
+ if (language.equals("\0")) {
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(language);
+ }
+
+ // Attmpt to load the resources
try {
- field.setAccessible(true);
- } catch (Exception ex) {
- // No-op; the callers might have used public fields, in
- // which case we don't need to make them accessible
+ resources = new Resources(baseName, locale, "UTF8");
+ } catch(SerializationException exception) {
+ throw new BindException(exception);
+ } catch(MissingResourceException exception) {
+ if (!defaultResources) {
+ throw new BindException(baseName + " not found.");
+ }
}
- }
- try {
- field.set(this, resource);
- } catch (IllegalAccessException exception) {
- throw new BindException(exception);
- }
- }
+ // Deserialize the value
+ WTKXSerializer wtkxSerializer = new WTKXSerializer(resources);
+ wtkxSerializers.put(fieldName, wtkxSerializer);
- Bind bindAnnotation = field.getAnnotation(Bind.class);
- if (bindAnnotation != null) {
- if (loadAnnotation != null) {
- throw new BindException("Cannot combine " + Load.class.getName()
- + " and " + Bind.class.getName() + " annotations.");
- }
+ URL location = type.getResource(loadAnnotation.name());
+ Object resource;
+ try {
+ resource = wtkxSerializer.readObject(location);
+ } catch (SerializationException exception) {
+ throw new BindException(exception);
+ }
- // Bind to the value loaded by the field's serializer
- String fieldName = bindAnnotation.resource();
- WTKXSerializer wtkxSerializer = wtkxSerializers.get(fieldName);
- if (wtkxSerializer == null) {
- throw new BindException("\"" + fieldName + "\" is not a valid resource name.");
+ // Set the deserialized value into the field
+ try {
+ field.set(this, resource);
+ } catch (IllegalAccessException exception) {
+ throw new BindException(exception);
+ }
}
- String id = bindAnnotation.id();
- if ("\0".equals(id)) {
- id = field.getName();
- }
+ Bind bindAnnotation = field.getAnnotation(Bind.class);
+ if (bindAnnotation != null) {
+ if (loadAnnotation != null) {
+ throw new BindException("Cannot combine " + Load.class.getName()
+ + " and " + Bind.class.getName() + " annotations.");
+ }
- Object value = wtkxSerializer.getObjectByName(id);
- if (value == null) {
- throw new BindException("\"" + id + "\" does not exist.");
- }
+ // Ensure that we can write to the field
+ if ((fieldModifiers & Modifier.FINAL) > 0) {
+ throw new BindException(fieldName + " is final.");
+ }
- // Set the value into the field
- if (!field.isAccessible()) {
- try {
- field.setAccessible(true);
- } catch (Exception ex) {
- // No-op; the callers might have used public fields, in
- // which case we don't need to make them accessible
+ if ((fieldModifiers & Modifier.PUBLIC) == 0) {
+ try {
+ field.setAccessible(true);
+ } catch(SecurityException exception) {
+ throw new BindException(fieldName + " is not accessible.");
+ }
+ }
+
+ // Bind to the value loaded by the property's serializer
+ String property = bindAnnotation.property();
+ WTKXSerializer wtkxSerializer = wtkxSerializers.get(property);
+ if (wtkxSerializer == null) {
+ throw new BindException("Property \"" + property + "\" has not been loaded.");
+ }
+
+ String id = bindAnnotation.id();
+ if (id.equals("\0")) {
+ id = field.getName();
}
- }
- try {
- field.set(this, value);
- } catch (IllegalAccessException exception) {
- throw new BindException(exception);
+ Object value = wtkxSerializer.getObjectByName(id);
+ if (value == null) {
+ throw new BindException("\"" + id + "\" does not exist.");
+ }
+
+ // Set the value into the field
+ try {
+ field.set(this, value);
+ } catch (IllegalAccessException exception) {
+ throw new BindException(exception);
+ }
}
}
}