openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r988644 [1/3] - in /openjpa/trunk/openjpa-examples/opentrader: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/openjpa/ src/main/java/org/apache/openjpa/trader/ src/main/java/org/apache...
Date Tue, 24 Aug 2010 18:11:27 GMT
Author: ppoddar
Date: Tue Aug 24 18:11:25 2010
New Revision: 988644

URL: http://svn.apache.org/viewvc?rev=988644&view=rev
Log:
First version of OpenTrader

Added:
    openjpa/trunk/openjpa-examples/opentrader/
    openjpa/trunk/openjpa-examples/opentrader/src/
    openjpa/trunk/openjpa-examples/opentrader/src/main/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingWindow.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/custom/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/event/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/event/ServiceEvent.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/event/ServiceEventHandler.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/ErrorDialog.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/FadeEffect.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/GridCellRenderer.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/HelpLink.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/MessageBox.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/ProgressMonitor.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ui/ScrollableTable.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Ask.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Bid.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/LogStatement.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Match.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Sector.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Stock.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Tradable.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Trade.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/Trader.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/domain/package.html   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/apache/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/apache/openjpa/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/apache/openjpa/util/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/apache/openjpa/util/LongId.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/override/org/apache/openjpa/util/OpenJPAId.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/server/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/server/ExceptionAdapter.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/server/TradingServiceAdapterImpl.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/BufferedLog.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/Exchange.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/MarketFeed.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/MockTradingService.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/PersistenceService.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/TradeEvent.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/TradingService.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/slice/
    openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/service/slice/SectorDistributionPolicy.java   (with props)
    openjpa/trunk/openjpa-examples/opentrader/src/main/resources/
    openjpa/trunk/openjpa-examples/opentrader/src/main/resources/css/
    openjpa/trunk/openjpa-examples/opentrader/src/main/resources/css/OpenTrader.css   (with props)

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml Tue Aug 24 18:11:25 2010
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module rename-to='opentrader'>
+  <!-- Inherit the core Web Toolkit stuff.                        -->
+  <inherits name='com.google.gwt.user.User'/>
+  <inherits name="com.google.gwt.resources.Resources" />
+  <!-- Inherit the default GWT style sheet.  You can change       -->
+  <!-- the theme of your GWT application by uncommenting          -->
+  <!-- any one of the following lines.                            -->
+  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
+  <inherits name='org.cobogw.gwt.user.User' />
+  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
+  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
+
+  <!-- Other module inherits                                      -->
+
+  <!-- Specify the app entry point class.                         -->
+  <entry-point class='org.apache.openjpa.trader.client.OpenTrader'/>
+
+  <!-- Specify the paths for translatable code                    -->
+  <source path='client'/>
+  <source path='domain'/>
+  
+  
+  <set-property name="user.agent" value="gecko1_8"/> 
+
+</module>

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/OpenTrader.gwt.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,97 @@
+/*
+ * 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.openjpa.trader.client;
+
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.ui.HTML;
+
+/**
+ * A set of static utilities to create decorated HTML labels for price and price changes.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class FormatUtil {
+    public static final NumberFormat priceFormat  = NumberFormat.getFormat("#,##0.00");
+    public static final NumberFormat changeFormat = NumberFormat.getFormat("+#,##0.00;-#,##0.00");
+    public static final NumberFormat volumeFormat = NumberFormat.getFormat("#,##0");
+    
+    /**
+     * Creates a HTML for the formatted price without any style.
+     */
+    public static HTML formatPrice(double price) {
+        return formatPrice(price, false);
+    }
+    
+    /**
+     * Creates a HTML label for the formatted price with a style based on the signum of the price.
+     * The positive and negative values are formatted with CSS styles <code>positive</code> and
+     * <code>negative</code> respectively.
+     */
+    public static HTML formatPrice(double price, boolean style) {
+        HTML label = new HTML();
+        label.setText(priceFormat.format(price));
+        if (style)
+            label.addStyleName(price >= 0 ? "positive" : "negative");
+        return label;
+    }
+    
+    /**
+     * Creates a HTML label for the given integer.
+     */
+    public static HTML formatVolume(int volume) {
+        HTML label = new HTML();
+        label.setText(volumeFormat.format(volume));
+        return label;
+    }
+    
+    /**
+     * Creates a HTML label for the difference of two given numbers and applies style based
+     * on the sign of the difference. Optionally adds percentage change.
+     * 
+     * @param p1 first value
+     * @param p2 second value
+     * @param pct if true, adds a percentage change
+     */
+    public static HTML formatChange(double p1, double p2, boolean pct) {
+        String raw = changeFormat.format(p1-p2);
+        if (pct && p1 != 0) {
+            double delta = p1 - p2;
+            String pctraw = changeFormat.format(100*delta/p1)+"%";
+            raw += " (" + pctraw + ")";
+        }
+        String style = p1 >= p2 ? "positive" : "negative";
+        HTML html = new HTML();
+        html.setText(raw);
+        html.addStyleName(style);
+        return html;
+    }
+    
+    /**
+     * Creates a HTML label for the given value and applies style based on the sign.
+     */
+    public static HTML formatChange(double c) {
+        HTML html = new HTML();
+        String raw = changeFormat.format(c);
+        String style = c >= 0 ? "positive" : "negative";
+        html.setText(raw);
+        html.addStyleName(style);
+        return html;
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/FormatUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,138 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.ui.MessageBox;
+import org.apache.openjpa.trader.client.ui.ProgressMonitor;
+import org.apache.openjpa.trader.domain.Stock;
+import org.apache.openjpa.trader.domain.Trader;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.TextBox;
+
+/**
+ * A dialog box for login a Trader. Once the trader's name is entered, this widget calls the server 
+ * to start a session for the trader, gets all the tradable Stocks and passes that initialization data
+ * to the {@link OpenTrader main application} to {@link OpenTrader#init(Trader, List) initialize}.
+ * 
+ * <br>
+ * CSS styles used
+ * <LI> login : for the main dialog box
+ * <LI> login-caption: for the caption
+ * 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class LoginDialog extends PopupPanel {
+    private Trader trader;
+    private final OpenTrader session;
+    
+    public LoginDialog(final OpenTrader session) {
+        super(false, true);
+
+        setAnimationEnabled(true);
+        this.session = session;
+        
+        final FlexTable table = new FlexTable();
+        final HTML header = new HTML("&nbsp;&nbsp;Welcome to OpenTrader&nbsp;&nbsp;");
+        final Label label  = new Label("Please enter name:");
+        DOM.setStyleAttribute(label.getElement(), "textAlign", "right");
+        final TextBox traderName = new TextBox();
+        traderName.setText("OpenTrader");
+        final Button enter = new Button("Enter");
+
+        addStyleName("login");
+        table.addStyleName("login");
+        label.addStyleName("login");
+        header.addStyleName("login-caption");
+                
+        table.setWidget(0, 0, header);
+        table.setWidget(2, 0, label);
+        table.setWidget(2, 1, traderName);
+        table.setWidget(4, 1, enter);
+        table.getFlexCellFormatter().setColSpan(0, 0, 2);
+
+        enter.setEnabled(true);
+        traderName.setFocus(true);
+        
+        enter.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                if (traderName.getText().trim().length() == 0) {
+                    MessageBox.alert("Trader's name must not be empty.");
+                    return;
+                }
+                hide();
+                ProgressMonitor.showProgress("Connecting to OpenTrader Server...");
+                session.getService().login(traderName.getText(), new LoginCallback());
+            }
+        });
+        setWidget(table);
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Asynchronous RPC service callbacks
+     * ---------------------------------------------------------------------------------
+     */
+
+    /**
+     * Logs in a [@link Trader} and then invokes another RPC service to get the list of tradable stocks.
+     * This pattern of calling one RPC from another addresses sequential execution of asynchronous
+     * callbacks. This pattern is necessary when the second RPC depends in some way to the result of
+     * the first RPC. 
+     * 
+     */
+    class LoginCallback implements AsyncCallback<Trader> {
+        public void onFailure(Throwable caught) {
+            ProgressMonitor.stop();
+            session.handleError(caught);
+        }
+        
+        public void onSuccess(Trader result) {
+            trader = result;
+            session.getService().getStocks(new InitializeStocks());
+        }
+    }
+    
+    /**
+     * Initializes the tradable stocks followed by the main application.
+     *
+     */
+    public class InitializeStocks implements AsyncCallback<List<Stock>> {
+        public void onFailure(Throwable caught) {
+            session.handleError(caught);
+        }
+
+        public void onSuccess(List<Stock> stocks) {
+            ProgressMonitor.stop();
+            session.init(trader, stocks);
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/LoginDialog.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,165 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.UpdateStockHandler;
+import org.apache.openjpa.trader.client.ui.GridCellRenderer;
+import org.apache.openjpa.trader.client.ui.ScrollableTable;
+import org.apache.openjpa.trader.domain.Stock;
+
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * Displays the current Stock prices and updates periodically.
+ * 
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+public class MarketDataPanel extends ScrollableTable<Stock> implements UpdateStockHandler {
+    private final OpenTrader session;
+    private Timer refreshTimer;
+    private static int refreshInterval = 60*1000;
+    
+    public MarketDataPanel(final OpenTrader session, final int w, final int h) {
+        super("Market Prices (Updated every " + refreshInterval/1000 + "s)", w, h, true);
+        this.session = session;
+        
+        session.registerHandler(ServiceEvent.StockUpdated.TYPE, this);
+        
+        setColumnHeader(0, "Symbol", "25%");
+        setColumnHeader(1, "Price",  "25%");
+        setColumnHeader(2, "Change", "50%");
+        
+        // Stock Symbol
+        setRenderer(0, new GridCellRenderer<Stock>() {
+            public Widget render(Stock stock) {
+                return new Label(stock.getSymbol());
+            }
+        });
+        
+        // Current Market Price
+        setRenderer(1, new GridCellRenderer<Stock>() {
+            public Widget render(Stock stock) {
+                return FormatUtil.formatPrice(stock.getMarketPrice());
+            }
+        });
+        
+        // Percent Change since last update
+        setRenderer(2, new GridCellRenderer<Stock>() {
+            public Widget render(Stock stock) {
+                return FormatUtil.formatChange(stock.getMarketPrice(), stock.getLastPrice(), true);
+            }
+        });
+    }
+    
+    /**
+     * Sets the interval to refresh the stock data from the server.
+     * 
+     * @param interval period in milliseconds.
+     */
+    public void setRefreshInterval(int interval) {
+        refreshInterval = interval;
+        setCaption("Market Prices (Updated every " + refreshInterval/1000 + "s)");
+        if (refreshTimer != null)
+            refreshTimer.scheduleRepeating(refreshInterval);
+    }
+    
+    /**
+     * Gets the interval (in milliseconds) to refresh  the stock data from the server.
+     */
+    public int getRefreshInterval() {
+        return refreshInterval;
+    }
+
+    /**
+     * Starts a periodic update of the stocks from the server.
+     */
+    public void startStockWatcher() {
+        if (refreshTimer != null)
+            return;
+        // Setup timer to refresh list automatically.
+        refreshTimer = new Timer() {
+            @Override
+            public void run() {
+                session.getService().getStocks(new UpdateStocks());
+            }
+        };
+        refreshTimer.run();
+        refreshTimer.scheduleRepeating(refreshInterval);
+    }
+    
+    /**
+     * Starts periodic update of the stocks from the server.
+     */
+    public void stopStockWatcher() {
+        if (refreshTimer == null)
+            return;
+        refreshTimer.cancel();
+        refreshTimer = null;
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Service Event Response Management
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * Updates the stock data.
+     */
+    @Override
+    public void onStockUpdated(ServiceEvent.StockUpdated event) {
+        update(event.getPayload(), null);
+    }
+
+
+    /**
+     * ---------------------------------------------------------------------------------
+     * Asynchronous RPC service callbacks
+     * ---------------------------------------------------------------------------------
+     */
+
+    /**
+     * Periodically update the stocks and notifies the listeners via the 
+     * {@link OpenTrader#fireEvent(com.google.gwt.event.shared.GwtEvent) mediator}.
+     * In this case, one of the listeners is this widget itself. Still the
+     * {@link ServiceEvent.StockUpdated service event} is propagated via the
+     * mediator (so that others can listen as well).
+     * 
+     */
+    public class UpdateStocks implements AsyncCallback<List<Stock>> {
+        public void onFailure(Throwable caught) {
+            session.handleError(caught);
+        }
+
+        public void onSuccess(List<Stock> result) {
+            int n = result.size();
+            for (int i = 0; i < n; i++) {
+                session.fireEvent(new ServiceEvent.StockUpdated(result.get(i)));
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MarketDataPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,144 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Match;
+import org.apache.openjpa.trader.domain.Tradable;
+import org.apache.openjpa.trader.domain.Trade;
+import org.apache.openjpa.trader.domain.Trader;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.RadioButton;
+
+/**
+ * A popup presents a list of matching Tradables and lets the user select one of them
+ * to commit a trade.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class MatchWindow extends PopupPanel {
+    private final OpenTrader session;
+    
+    public MatchWindow(final OpenTrader session, final Tradable tradable, final List<Match> matches) {
+        super(false, true);
+        this.session = session;
+
+        final boolean ask = (tradable instanceof Ask);
+
+        final RadioButton[] buttons = new RadioButton[matches.size()];
+        FlowPanel panel = new FlowPanel();
+        
+        String txt = (matches.isEmpty() ? "No" : matches.size()) + " matching " + (ask ? "Bid" : "Ask") 
+                       + " for " + toString(tradable) + "<br>";
+        HTML html = new HTML();
+        html.setHTML(txt);
+        html.addStyleName("table-caption");
+        panel.add(html);
+        
+        if (!matches.isEmpty()) {
+            FlexTable table = new FlexTable();
+            for (int i = 0;  i < matches.size(); i++) {
+                Match match = matches.get(i);
+                Tradable t2 = ask ? match.getBid() : match.getAsk();
+                Trader cpty = ask ? match.getBid().getBuyer() : match.getAsk().getSeller();
+                buttons[i] = new RadioButton("matches");
+                buttons[i].setValue(i == 0);
+                table.setWidget(i, 0, buttons[i]);
+                table.setWidget(i, 1, FormatUtil.formatPrice(t2.getPrice()));
+                table.setWidget(i, 2, FormatUtil.formatVolume(t2.getVolume()));
+                table.setText(i, 3, " by " + cpty.getName());
+            }
+            panel.add(table);
+            panel.add(new HTML("<p>"));
+            
+            Button act = new Button(ask ? "Sell" : "Buy");
+            panel.add(act);
+            act.addClickHandler(new ClickHandler() {
+                public void onClick(ClickEvent event) {
+                    for (int i = 0; i < buttons.length; i++) {
+                        if (buttons[i].getValue()) {
+                            Match match = matches.get(i);
+                            Tradable t = ask ? match.getAsk() : match.getBid();
+                            session.getService().trade(match, new TradeCallback(t));
+                            hide(true);
+                        }
+                    }
+                }
+            });
+        } else {
+            panel.add(new HTML("<p>"));
+        }
+        Button cancel = new Button("Cancel");
+        panel.add(cancel);
+        cancel.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent event) {
+                hide(true);
+            }
+        });
+        add(panel);
+    }
+    
+    String toString(Tradable t) {
+        return "" + t.getVolume() + " of " + t.getStock().getSymbol() + " at price " 
+        + FormatUtil.priceFormat.format(t.getPrice());
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Asynchronous RPC service callbacks
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * Commits a Trade and notifies the listeners to {@link ServiceEvent.TradableRemoved
+     * remove} the {@link Tradable tradable} and newly {@link ServiceEvent.TradeCommitted committed}
+     * {@link Trade trade}.
+     * <br>
+     * This is an example of a callback that has a input state (the tradable entity). On completion
+     * of the asynchronous RPC, this function will notify the listeners with the newly commited trade
+     * which is the result of the callback invocation, as well as the input tradable entity.
+     */
+    public class TradeCallback implements AsyncCallback<Trade> {
+        private final Tradable tradable;
+        
+        public TradeCallback(Tradable m) {
+            tradable = m;
+        }
+        public void onFailure(Throwable caught) {
+            session.handleError(caught);
+        }
+
+        public void onSuccess(Trade trade) {
+            session.fireEvent(new ServiceEvent.TradableRemoved(tradable));                         
+            session.fireEvent(new ServiceEvent.TradeCommitted(trade));
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/MatchWindow.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,42 @@
+/*
+ * 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.openjpa.trader.client;
+
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
+
+/**
+ * A bundle  of resources (a couple of tiny images for now). However, GWT framework
+ * seems to have generalized and added performance boost to handle heavy resources
+ * such as images to be loaded from the web server. 
+ * <br>
+ * This sample application does not explore this feature of GWT, only other than
+ * applying a singleton pattern. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public interface OpenTradeImageBundle extends ClientBundle {
+    
+    @Source("images/login.gif")
+    public ImageResource login();
+    
+    @Source("images/logo.gif")
+    public ImageResource logo();
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTradeImageBundle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,311 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.client.ui.ErrorDialog;
+import org.apache.openjpa.trader.client.ui.ScrollableTable;
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Bid;
+import org.apache.openjpa.trader.domain.Stock;
+import org.apache.openjpa.trader.domain.Trade;
+import org.apache.openjpa.trader.domain.Trader;
+import org.apache.openjpa.trader.service.TradingService;
+import org.cobogw.gwt.user.client.ui.RoundedPanel;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.GwtEvent;
+import com.google.gwt.event.shared.HandlerManager;
+import com.google.gwt.event.shared.GwtEvent.Type;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.DockLayoutPanel;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootLayoutPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * The GWT module for OpenTrader.
+ * 
+ * <br><b>Initialization</b>:
+ * This module entry point acts as the Application Controller.
+ * It initializes the widget components and lays them out. As it is often the case, some of 
+ * the widgets require initialization data. 
+ * Hence, this entry point establishes connection to remote {@link TradingService} via 
+ * {@link TradingServiceAdapterAsync asynchronous}, client-side, proxy stub. The GWT
+ * framework provides that stub when supplied with the original interface class.
+ * <br>
+ * <b>Operation</b>:
+ * Once initialized, the widgets operate relatively independently throughout the rest of the 
+ * operations. Each widget provides a view and invokes server functions (asynchronously via
+ * RPC) to update the view. 
+ * <br>
+ * <b>Event Management</b>:
+ * The widgets communicate to other widgets via this module entry point i.e.
+ * if the server callback results from a view action requires to update another view, then the request 
+ * is relayed through this entry point instead of one view calling the other directly.
+ * The GWT framework does provide the core infrastructure for
+ * DOM and user event propagation. This entry point reuses the same infrastructure with
+ * the application-defined specialized {@link ServiceEvent <em>service events</em>} to represent 
+ * the <em>business</em> functions such as a new Ask or Bid request is placed, or a Trade
+ * committed etc.  
+ * <br>
+ * <b>Session State Management</b>: One of the core advantages of GWT framework (apart from ease
+ * of development and out-of-the-box cross-browser compatibility), is that GWT allows the client to
+ * maintain its own state, thereby opening up the possibility of state-less (or at least less
+ * stateful and hence more scalable) servers. This client maintains its session state in the
+ * {@link ScrollableTable#getModel() data models} of the core widgets. The only <em>common,
+ * shared</em> state held by this Application Controller is the logged-in {@link Trader}.   
+ * 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class OpenTrader implements EntryPoint, UncaughtExceptionHandler {
+    // Event management
+    private HandlerManager  eventBus;
+    
+    // The main widget components
+    private MarketDataPanel stockPanel;               // the market prices 
+    private TradeOrderWindow orderPanel;              // Creates a Ask/Bid request
+    private TradingWindow   tradePanel;               // Issues a trade order
+    private ScrollableTable<Trade> soldTradePanel;    // displays committed trades
+    private ScrollableTable<Trade> boughtTradePanel;  // displays committed trades
+    private ServerLogPanel serverPanel;               // displays server logs
+    
+    
+    // Server-State variables as Session Identifier
+    private Trader trader;
+
+    // The handle to the remote service.
+    private TradingServiceAdapterAsync tradingService;
+
+    // Resource bundle for images etc.
+    public static final OpenTradeImageBundle bundle = GWT.create(OpenTradeImageBundle.class);
+    
+    /**
+     * ------------------------------------------------------------------------
+     * The entry point for GWT module.
+     * ------------------------------------------------------------------------
+     */
+    public void onModuleLoad() {
+        GWT.setUncaughtExceptionHandler(this);
+        eventBus = new HandlerManager(this);
+        new LoginDialog(this).center();
+    }
+       
+    /**
+     * Gets the handle to the remote service. The service handle is the asynchronous interface
+     * but it is created by the GWT framework from the synchronous interface class literal. 
+     */
+    public TradingServiceAdapterAsync getService() {
+        if (tradingService == null) {
+            tradingService = GWT.create(TradingServiceAdapter.class);
+        }
+        return tradingService;
+    }
+    
+    /**
+     * Gets the name of the trader as the name of this session.
+     */
+    public String getName() {
+        return trader == null ? "" : trader.getName();
+    }
+    
+    /**
+     * Gets the trader who is running this session.
+     */
+    public Trader getTrader() {
+        return trader;
+    }
+    
+    /**
+     * Gets all the traded stocks traded by the service.
+     * The stocks are maintained by the {@link ScrollableTable#getModel() data model} of
+     * the Market Data Panel widget.
+     */
+    public List<Stock> getTradedStocks() {
+        return stockPanel.getModel();
+    } 
+    
+    /**
+     * Builds up the widgets once the login is complete i.e. the server has supplied
+     * the initialization data.
+     * 
+     */
+    void init(Trader trader, List<Stock> stocks) {
+        this.trader = trader;
+        
+        Window.setTitle(trader.getName());
+
+        int W = Window.getClientWidth();
+        int H = 900;//Window.getClientHeight();
+        
+                                       int headerHeight = 05*H/100;
+        int westWidth   = 25*W/100;    int westHeight   = 80*H/100;
+        int centerWidth = 60*W/100;    int centerHeight = 80*H/100;
+                                       int footerHeight = 02*H/100;
+        Unit unit = Unit.PX;
+
+        stockPanel       = new MarketDataPanel(this, westWidth-10, 40*westHeight/100);
+        int N = stocks.size();
+        for (int i = 0; i < N; i++) {
+            stockPanel.insert(stocks.get(i));
+        }
+        
+        soldTradePanel   = new TradeHistoryPanel(this, Ask.class, westWidth-10, 20*westHeight/100);
+        boughtTradePanel = new TradeHistoryPanel(this, Bid.class, westWidth-10, 20*westHeight/100);
+        serverPanel      = new ServerLogPanel(this,  centerWidth, 40*centerHeight/100);
+        tradePanel       = new TradingWindow(this,   centerWidth, 40*centerHeight/100);
+        orderPanel       = new TradeOrderWindow(this,centerWidth, 10*centerHeight/100);
+
+        
+        FlowPanel west = new FlowPanel();
+        west.setSize((westWidth-10)+"px", westHeight+"px");
+        west.add(decorate(stockPanel));
+        west.add(new HTML("<p>"));
+        west.add(decorate(soldTradePanel));
+        west.add(new HTML("<p>"));
+        west.add(decorate(boughtTradePanel));
+        
+        FlowPanel center = new FlowPanel();
+        center.setSize(centerWidth+"px", centerHeight+"px");
+        center.add(decorate(orderPanel));
+        center.add(new HTML("<p>"));
+        center.add(decorate(tradePanel));
+        center.add(new HTML("<p>"));
+        center.add(decorate(serverPanel));
+        
+        DockLayoutPanel main = new DockLayoutPanel(unit);
+        
+        main.addNorth(createHeader(), headerHeight);
+        main.addSouth(createFooter(), footerHeight);
+        main.addWest(west, westWidth);
+        main.add(center);
+
+        RootLayoutPanel.get().add(main);
+        main.animate(500);
+        setUpHelp();
+        stockPanel.startStockWatcher();
+        tradePanel.startTradableRefresher();
+    }
+    
+    /**
+     * Decorates an widget by wrapping in a rounded panel (that seems to be cool thing nowadays).
+     */
+    Widget decorate(Widget w) {
+        RoundedPanel rp = new RoundedPanel(w,RoundedPanel.ALL, 2);
+        rp.setBorderColor("#005B9A");
+        return rp;
+    }
+    
+    /**
+     * Sets up a help page for each of the main widgets.
+     * 
+     * @see ScrollableTable#addHelp(String)
+     */
+    void setUpHelp() {
+        stockPanel.addHelp("help/MarketData.html");
+        tradePanel.addHelp("help/Trade.html");
+        orderPanel.addHelp("help/TradeOrder.html");
+        soldTradePanel.addHelp("help/CommittedTrade.html");
+        boughtTradePanel.addHelp("help/CommittedTrade.html");
+        serverPanel.addHelp("help/Logging.html");
+    }
+    
+    /**
+     * Creates a header panel. Uses the image resources for a logo and a banner text.
+     */
+    Widget createHeader() {
+        HorizontalPanel panel = new HorizontalPanel();
+        Image logo = new Image(bundle.logo());
+        HTML banner = new HTML("OpenTrader");
+        banner.setStylePrimaryName("header");
+        panel.add(logo);
+        panel.add(banner);
+        return panel;
+    }
+    
+    /**
+     * Creates a footer panel. 
+     */
+    Widget createFooter() {
+        HorizontalPanel panel = new HorizontalPanel();
+        Label footer = new HTML("Built with OpenJPA/Slice and GWT");
+        footer.setStylePrimaryName("footer");
+        panel.add(footer);
+        return panel;
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Error Handling
+     * ---------------------------------------------------------------------------------
+     */
+    /**
+     * Catches any uncaught exception and pops up a {@link ErrorDialog error dialog}.
+     */
+    public void onUncaughtException(Throwable t) {
+        handleError(t);
+    }
+    
+    /**
+     * Pops up a modal {@link ErrorDialog error dialog} with the given error.
+     */
+    void handleError(Throwable t) {
+        t.printStackTrace();
+        ErrorDialog.showError(t);
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Service Event Handling
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * Registers a event with its handler. This mediator pattern facilitates communication
+     * between the component widgets without them being aware of each other.
+     * <br>
+     * GWT framework supports this patter out-of-the-box. This application reuses the
+     * framework for a set of {@link ServiceEvent service events}. 
+     */
+    public <H extends EventHandler> void registerHandler(Type<H> eventType, H handler) {
+        eventBus.addHandler(eventType, handler);
+    }
+    
+    /**
+     * Fires a event to the registered handlers.
+     * 
+     * @param event can be any GwtEvent but used here for specialized {@link ServiceEvent service events}. 
+     */
+    public void fireEvent(GwtEvent<? extends EventHandler> event) {
+        eventBus.fireEvent(event);
+    }
+    
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/OpenTrader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,159 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.AddTradableHandler;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.AddTradeHandler;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.RemoveTradableHandler;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.UpdateStockHandler;
+import org.apache.openjpa.trader.client.ui.GridCellRenderer;
+import org.apache.openjpa.trader.client.ui.ScrollableTable;
+import org.apache.openjpa.trader.domain.LogStatement;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * One of the component widgets to display the server logs.
+ * The log messages are parsed to determine whether they are SQL statements and further
+ * categorized as SELECT, INSERT, UPDATE or DELETE to add a decorative CSS style.
+ * <br>
+ * CSS styles are
+ * <LI>sql-insert
+ * <LI>sql-update
+ * <LI>sql-select
+ * <LI>sql-delete
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class ServerLogPanel extends ScrollableTable<LogStatement> 
+    implements AddTradableHandler, RemoveTradableHandler, 
+    AddTradeHandler, UpdateStockHandler {
+    final OpenTrader session;
+    public static final String[] MARKERS_AND_STYLES = {"SELECT", "INSERT", "UPDATE", "DELETE"}; 
+    
+    
+    public ServerLogPanel(final OpenTrader session, final int w, final int h) {
+        super("Server Logs", w,h, false);
+        this.session = session;
+        
+        session.registerHandler(ServiceEvent.TradableAdded.TYPE, this);
+        session.registerHandler(ServiceEvent.TradableRemoved.TYPE, this);
+        session.registerHandler(ServiceEvent.TradeCommitted.TYPE, this);
+        session.registerHandler(ServiceEvent.StockUpdated.TYPE, this);
+
+        setColumnHeader(0, "Context", "10%");
+        setColumnHeader(1, "Message", "90%");
+        
+        setRenderer(0, new GridCellRenderer<LogStatement>() {
+            public Widget render(LogStatement log) {
+                return new Label(log.getContext());
+           }
+        });
+        setRenderer(1, new GridCellRenderer<LogStatement>() {
+            public Widget render(LogStatement log) {
+                return decorate(log.getMessage(), MARKERS_AND_STYLES);
+           }
+        });
+    }
+    
+    HTML decorate(String s, String[] markersAndStyles) {
+            HTML html = new HTML(s);
+            String style = getStyle(s, MARKERS_AND_STYLES);
+            if (style != null)
+                html.addStyleName(style);
+            return html;
+    }
+    
+    static String getStyle(String s, String[] markersAndStyles) {
+        String style = null;
+        for (int i = 0; i < markersAndStyles.length; i++) {
+            String marker = markersAndStyles[i];
+            int n = marker.length();
+            if (s.length() < n) {
+                continue;
+            }
+            String preamble = s.substring(0,n);
+            if (preamble.equalsIgnoreCase(marker)) {
+                style = "sql-"+marker.toLowerCase();
+                return style;
+            }
+        }
+        return null;
+    }
+    
+    private void log() {
+        session.getService().getLog(new LoggingCallback());
+    }
+
+    /**
+     * ---------------------------------------------------------------------------------
+     * Service Event Response Management
+     * 
+     * This widget receives all service event update and logs the corresponding server
+     * logs.
+     * ---------------------------------------------------------------------------------
+     */
+    public void onTradableAdded(ServiceEvent.TradableAdded event) {
+        log();
+    }
+
+    public void onTradableRemoved(ServiceEvent.TradableRemoved event) {
+        log();
+    }
+
+    public void onTradeCommitted(ServiceEvent.TradeCommitted event) {
+        log();
+    }
+
+    public void onStockUpdated(ServiceEvent.StockUpdated event) {
+        log();
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Asynchronous RPC service callbacks
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * Unlike other callbacks, this callback on completion does not broadcast the log messages.
+     * Instead it simply inserts the message in its own tabular display.  
+     */
+    public class LoggingCallback implements AsyncCallback<List<LogStatement>> {
+        public void onFailure(Throwable caught) {
+            session.handleError(caught);
+        }
+
+        public void onSuccess(List<LogStatement> messages) {
+            if (messages == null)
+                return;
+            int N = messages.size();
+            for (int i = 0; i < N; i++) {
+               insert(messages.get(i));
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/ServerLogPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,109 @@
+/*
+ * 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.openjpa.trader.client;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler;
+import org.apache.openjpa.trader.client.ui.GridCellRenderer;
+import org.apache.openjpa.trader.client.ui.ScrollableTable;
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Bid;
+import org.apache.openjpa.trader.domain.Tradable;
+import org.apache.openjpa.trader.domain.Trade;
+import org.apache.openjpa.trader.domain.Trader;
+
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * One of the core component widgets to display the committed trades.
+ * The panel is configured for either {@link Ask} or {@link Bid} and
+ * accordingly it adjusts some of its labels or contents.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class TradeHistoryPanel extends ScrollableTable<Trade> 
+    implements ServiceEventHandler.AddTradeHandler {
+    
+    private final OpenTrader session;
+    private final Class<? extends Tradable> _type;
+    
+    public TradeHistoryPanel(final OpenTrader session, Class<? extends Tradable> type, 
+            final int w, final int h) {
+        super("Stocks " + (type == Ask.class ? "sold" : "bought") + " by " + session.getName(), w,h, true);
+        this.session = session;
+        this._type = type;
+        
+        session.registerHandler(ServiceEvent.TradeCommitted.TYPE, this);
+        
+        setColumnHeader(0, "Stock",  "20%");
+        setColumnHeader(1, "Price",  "20%");
+        setColumnHeader(2, "Volume", "20%");
+        setColumnHeader(3, type == Ask.class ? "Buyer" : "Seller",  "40%");
+        
+        // Stock symbol
+        setRenderer(0, new GridCellRenderer<Trade>() {
+            public Widget render(Trade model) {
+                return new Label(model.getStock().getSymbol());
+           }
+        });
+        
+        // Price of the trade
+        setRenderer(1, new GridCellRenderer<Trade>() {
+            public Widget render(Trade t) {
+                return FormatUtil.formatPrice(t.getPrice());
+           }
+        });
+        
+        // Volume of the trade
+        setRenderer(2, new GridCellRenderer<Trade>() {
+            public Widget render(Trade t) {
+                return FormatUtil.formatVolume(t.getVolume());
+           }
+        });
+        
+        // Counter Party
+        setRenderer(3, new GridCellRenderer<Trade>() {
+            public Widget render(Trade t) {
+                Trader cpty = session.getTrader().equals(t.getBuyer()) ? t.getSeller() : t.getBuyer(); 
+                return new Label(cpty.getName());
+           }
+        });
+    }
+
+    /**
+     * ---------------------------------------------------------------------------------
+     * Service Event Response Management
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * On receipt of the event determines if it is relevant for this instance.
+     * Because an instance display either the Trades sold or bought.
+     * If relevant then updates the display. 
+     */
+    public void onTradeCommitted(ServiceEvent.TradeCommitted event) {
+        Trader trader = session.getTrader();
+        if ((trader.equals(event.getPayload().getSeller()) && _type == Ask.class) 
+         || (trader.equals(event.getPayload().getBuyer())  && _type == Bid.class)) {   
+            insert(event.getPayload());
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeHistoryPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,316 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.util.List;
+
+import org.apache.openjpa.trader.client.event.ServiceEvent;
+import org.apache.openjpa.trader.client.event.ServiceEventHandler.UpdateStockHandler;
+import org.apache.openjpa.trader.client.ui.HelpLink;
+import org.apache.openjpa.trader.client.ui.MessageBox;
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Bid;
+import org.apache.openjpa.trader.domain.Stock;
+
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.TextBox;
+
+/**
+ * This Widget allows the user to enter the details of a trade order (an Ask or
+ * Bid) and call the {@link TradingServiceAdapterAsync Trading Service} via asynchronous RPC 
+ * callback to record the order.
+ * <br>
+ * The widget demonstrates the aspect where a displayed element can change either
+ * because other elements within the same widget are changing or because some external
+ * state is changing. For example, the gain/loss of a requested buy/sell offer can
+ * change as the user enters a different price. It can also change if the market
+ * price of the stock has changed externally. The former changes are handled by adding
+ * event handlers to the widget elements (such as onKeyUp in a text box), the later
+ * changes are notified by this widget registering to the {@link OpenTrader main application}.   
+ * 
+ * 
+ * @author Pinaki Poddar
+ * 
+ */
+class TradeOrderWindow extends FlexTable implements UpdateStockHandler {
+    private final OpenTrader session;
+    final ListBox symbols     = new ListBox(false);
+    final Button ask          = new Button("Ask");
+    final Button bid          = new Button("Bid");
+    final TextBox marketPrice = new TextBox();
+    final TextBox userPrice   = new TextBox();
+    final TextBox userVolume  = new TextBox();
+    final TextBox margin      = new TextBox();
+    final TextBox gain        = new TextBox();
+
+    public TradeOrderWindow(final OpenTrader session, int w, int h) {
+        super();
+        this.session = session;
+
+        setPixelSize(w, h);
+        setStyleName("TradeOrderWindow");
+
+        session.registerHandler(ServiceEvent.StockUpdated.TYPE, this);
+        
+        marketPrice.setReadOnly(true);
+        margin.setReadOnly(true);
+        gain.setReadOnly(true);
+        userPrice.setMaxLength(10);
+        userVolume.setMaxLength(10);
+
+        setCellPadding(-2);
+        setCellSpacing(-1);
+        setHTML(0, 0, "Stock");
+        setHTML(0, 1, "Market");
+        setHTML(0, 2, session.getName());
+        setHTML(0, 3, "Margin");
+        setHTML(0, 4, "Volume");
+        setHTML(0, 5, "Gain/Loss");
+        for (int i = 0; i < 5; i++) {
+            getCellFormatter().addStyleName(0, i, "TradingWindow-Label");
+        }
+
+        setWidget(1, 0, symbols);
+        setWidget(1, 1, marketPrice);
+        setWidget(1, 2, userPrice);
+        setWidget(1, 3, margin);
+        setWidget(1, 4, userVolume);
+        setWidget(1, 5, gain);
+
+        setWidget(2, 2, ask);
+        setWidget(2, 3, bid);
+
+        DOM.setStyleAttribute(getRowFormatter().getElement(0), "height", "4px");
+        userPrice.setFocus(true);
+        userPrice.setTabIndex(1);
+        userPrice.setTabIndex(2);
+        ask.setTabIndex(3);
+        bid.setTabIndex(4);
+
+        userPrice.addKeyUpHandler(new KeyUpHandler() {
+            public void onKeyUp(KeyUpEvent event) {
+                if (userPrice.getText().trim().length() == 0)
+                    return;
+                double price = 0.0;
+                try {
+                    price = Double.parseDouble(userPrice.getText());
+                } catch (NumberFormatException e) {
+                    MessageBox.alert(userPrice.getText() + " must be a number");
+                    return;
+                }
+                double diff = calculateDiff(price, getSelectedStock().getMarketPrice());
+                margin.setText(FormatUtil.priceFormat.format(diff));
+                gain.setText(FormatUtil.changeFormat.format(diff * Integer.parseInt(userVolume.getText())));
+            }
+        });
+        userVolume.addKeyUpHandler(new KeyUpHandler() {
+            public void onKeyUp(KeyUpEvent event) {
+                if (userVolume.getText().trim().length() == 0)
+                    return;
+                int volume = 0;
+                try {
+                    volume = Integer.parseInt(userVolume.getText());
+                } catch (NumberFormatException e) {
+                    MessageBox.alert(userVolume.getText() + " must be a positive integer");
+                    return;
+                }
+                if (volume <= 0) {
+                    MessageBox.alert(userVolume.getText() + " must be a positive integer");
+                    return;
+                }
+                double diff = Double.parseDouble(margin.getText());
+                gain.setText(FormatUtil.changeFormat.format(diff * volume));
+            }
+        });
+        
+        List<Stock> stocks = session.getTradedStocks();
+        int n = stocks.size();
+        for (int i = 0; i < n; i++) {
+            symbols.addItem(stocks.get(i).getSymbol());
+        }
+        symbols.setSelectedIndex(0);
+        initialize(stocks.get(0), false);
+
+        symbols.addChangeHandler(new ChangeHandler() {
+            @Override
+            public void onChange(ChangeEvent event) {
+                Stock stock = getSelectedStock();
+                initialize(stock, false);
+            }
+        });
+
+        ask.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent ce) {
+                if (!validateData())
+                    return;
+                session.getService().ask(session.getTrader(), 
+                        getSelectedStock(), 
+                        Integer.parseInt(userVolume.getText()),
+                        Double.parseDouble(userPrice.getText()), 
+                        new AskCallback());
+            }
+        });
+
+        bid.addClickHandler(new ClickHandler() {
+            public void onClick(ClickEvent ce) {
+                if (!validateData())
+                    return;
+                session.getService().bid(session.getTrader(), 
+                        getSelectedStock(), 
+                        Integer.parseInt(userVolume.getText()),
+                        Double.parseDouble(userPrice.getText()), 
+                        new BidCallback());
+            }
+        });
+
+    }
+
+    /**
+     * Sets the content of the widgets based on the given stock. The widget
+     * content depends on the current stock price as well as user entered
+     * values. 
+     * 
+     * @param stock
+     * @param retainUserValue
+     */
+    void initialize(Stock stock, boolean retainUserValue) {
+        marketPrice.setText(FormatUtil.priceFormat.format(stock.getMarketPrice()));
+        if (retainUserValue && userPrice.getText().length() > 0) {
+            double diff = calculateDiff(Double.parseDouble(userPrice.getText()), stock.getMarketPrice());
+            margin.setText(FormatUtil.priceFormat.format(diff));
+            gain.setText(FormatUtil.priceFormat.format(diff * Integer.parseInt(userVolume.getText())));
+        } else {
+            userPrice.setText(FormatUtil.priceFormat.format(stock.getMarketPrice()));
+            userVolume.setText(FormatUtil.volumeFormat.format(100));
+            margin.setText(FormatUtil.priceFormat.format(0));
+            gain.setText(FormatUtil.priceFormat.format(0));
+        }
+    }
+    
+    public void addHelp(final String url) {
+        HelpLink help = new HelpLink(url);
+        setWidget(0, 6, help);
+        getCellFormatter().setAlignment(0, 6, 
+                HasHorizontalAlignment.ALIGN_RIGHT, HasVerticalAlignment.ALIGN_MIDDLE);
+    }
+
+    Stock getSelectedStock() {
+        return session.getTradedStocks().get(symbols.getSelectedIndex());
+    }
+
+    boolean validateData() {
+        try {
+            if (Double.parseDouble(userPrice.getText()) <= 0) {
+                MessageBox.alert("Price [" + userPrice.getText() + "] must be positive number");
+                return false;
+            }
+        } catch (NumberFormatException e) {
+            MessageBox.alert("Price [" + userPrice.getText() + "] must be a positive number");
+            return false;
+        }
+        try {
+            if (Integer.parseInt(userVolume.getText()) <= 0) {
+                MessageBox.alert("Volume [" + userVolume.getText() + "] must be a positive integer");
+                return false;
+            }
+        } catch (NumberFormatException e) {
+            MessageBox.alert("Volume [" + userVolume.getText() + "] must be a positive integer");
+            return false;
+        }
+        return true;
+    }
+
+    double calculateDiff(double p1, double p2) {
+        return truncate(Math.abs(p1-p2));
+    }
+    
+    private static double truncate (double x){
+        double fract;
+        double whole;
+        if ( x > 0 ){
+          whole = Math.floor(x);
+          fract = Math.floor( (x - whole) * 100) / 100;
+        } else {
+          whole = Math.ceil(x);
+          fract = Math.ceil( (x - whole) * 100) / 100;
+        }
+        return whole + fract;
+      }
+    
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Service Event Response Management
+     * ---------------------------------------------------------------------------------
+     */
+    public void onStockUpdated(ServiceEvent.StockUpdated event) {
+        Stock updated = event.getPayload();
+        Stock current = getSelectedStock();
+        if (updated.equals(current)) {
+            initialize(updated, true);
+        }
+    }
+    
+    /**
+     * ---------------------------------------------------------------------------------
+     * Asynchronous RPC service callbacks
+     * ---------------------------------------------------------------------------------
+     */
+    
+    /**
+     * Updates display once the offer to sell has been successfully placed.
+     * 
+     */
+    class AskCallback implements AsyncCallback<Ask> {
+        public void onSuccess(Ask result) {
+            session.fireEvent(new ServiceEvent.TradableAdded(result));
+        }
+        
+        public void onFailure(Throwable caught) {
+            session.handleError(caught);
+        }
+    }
+
+    /**
+     * Updates display once the offer to buy has been successfully placed.
+     * 
+     */
+    class BidCallback implements AsyncCallback<Bid> {
+       public void onSuccess(Bid result) {
+            session.fireEvent(new ServiceEvent.TradableAdded(result));
+       }
+       
+       public void onFailure(Throwable caught) {
+           session.handleError(caught);
+       }
+
+    }
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradeOrderWindow.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,106 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Bid;
+import org.apache.openjpa.trader.domain.LogStatement;
+import org.apache.openjpa.trader.domain.Match;
+import org.apache.openjpa.trader.domain.Stock;
+import org.apache.openjpa.trader.domain.Tradable;
+import org.apache.openjpa.trader.domain.Trade;
+import org.apache.openjpa.trader.domain.Trader;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+
+/**
+ * The client side stub for the RPC service.
+ * <br>
+ * This is a delegating interface to the original {@link TradingService} interface. This delegation
+ * pattern serves several purposes
+ * <LI> a) the delegator adds RuntimeException to each of the original service methods. 
+ * The original {@link TradingService} has not defined the exception in its method signature, 
+ * However, the actual implementation of {@link TradingService} is based on
+ * JPA and hence will throw <code>javax.persistence.PersistenceException</code>. To propagate
+ * these exceptions to the client, these exceptions need to be translated for serialization by 
+ * GWT compiler and will bring in heavier dependency. 
+ * <br>
+ * On the other hand, GWT will not propagate a non-translatable exception to the client,
+ * thereby making develop-debug cycles harder.
+ * <LI> b) GWT requires the service interface to extend GWT-defined 
+ * <code>com.google.gwt.user.client.rpc.RemoteService</code>. But the discipline used for this
+ * application dictates that the <em>service interface</em> be independent of either
+ * how it is implemented or how it will be accessed. That is why original {@link TradingService}
+ * definition neither depends on <code>javax.persistence.*</code> nor on <code>com.google.gwt.*</code>.
+ * <p>
+ * Because the interface is delegated, it is not necessary to have the same method name or 
+ * even signature. It may not have to declare all the original service interface methods either.
+ * <p>
+ * 
+ * Any type appearing in this interface must be serializable per GWT requirement.
+ */
+
+/**
+ * This <code>@RemoteServiceRelativePath</code> annotation defines the relative URL of the
+ * deployed servlet. It appears in <code>web.xml</code> as: 
+ * <pre>
+ *  &lt;servlet-mapping>
+ *       &lt;servlet-name>opentrader&lt;/servlet-name>
+ *       &lt;url-pattern>/opentrader/<b>trade</b>&lt;/url-pattern>
+ *   &lt;/servlet-mapping>
+ *  </pre>
+ *  <p>
+ *  The servlet name matches the name used in module descriptor <code>OpenTrader.gwt.xml</code> as
+ *  <pre>
+ *  &lt;module rename-to='opentrader'>
+ *  </pre>
+ */
+@RemoteServiceRelativePath("trade")
+public interface TradingServiceAdapter extends RemoteService {
+    Trader login(String name) 
+           throws RuntimeException;
+    List<Stock> getStocks()   
+           throws RuntimeException;
+    Ask ask(Trader trader, Stock stock, int volume, double price) 
+           throws RuntimeException;
+    Bid bid(Trader trader, Stock stock, int volume, double price) 
+           throws RuntimeException;
+    Tradable withdraw(Tradable t) 
+           throws RuntimeException;
+    Tradable refresh(Tradable t)  
+           throws RuntimeException;
+    List<Match> matchBid(Bid bid) 
+           throws RuntimeException;
+    List<Match> matchAsk(Ask ask) 
+           throws RuntimeException;
+    Trade trade(Match match)      
+           throws RuntimeException;
+    List<Trade> getTrades(Timestamp from, Timestamp to) 
+           throws RuntimeException;
+    List<Trade> getTrades(Trader trader, Boolean boughtOrsold, Timestamp from, Timestamp to) 
+           throws RuntimeException;
+    Stock getStock(String symbol) 
+           throws RuntimeException;
+    List<LogStatement> getLog() 
+           throws RuntimeException;
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java?rev=988644&view=auto
==============================================================================
--- openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java (added)
+++ openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java Tue Aug 24 18:11:25 2010
@@ -0,0 +1,71 @@
+/*
+ * 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.openjpa.trader.client;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+import org.apache.openjpa.trader.domain.Ask;
+import org.apache.openjpa.trader.domain.Bid;
+import org.apache.openjpa.trader.domain.LogStatement;
+import org.apache.openjpa.trader.domain.Match;
+import org.apache.openjpa.trader.domain.Stock;
+import org.apache.openjpa.trader.domain.Tradable;
+import org.apache.openjpa.trader.domain.Trade;
+import org.apache.openjpa.trader.domain.Trader;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * The asynchronous counterpart of the interface.
+ * The equivalence between this asynchronous interface and its {@link TradingServiceAdapter 
+ * synchronous version} is validated during GWT compilation.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public interface TradingServiceAdapterAsync {
+
+    void ask(Trader trader, Stock stock, int volume, double price, AsyncCallback<Ask> callback);
+
+    void bid(Trader trader, Stock stock, int volume, double price, AsyncCallback<Bid> callback);
+
+    void getStock(String symbol, AsyncCallback<Stock> callback);
+
+    void getStocks(AsyncCallback<List<Stock>> callback);
+
+    void getTrades(Timestamp from, Timestamp to, AsyncCallback<List<Trade>> callback);
+
+    void getTrades(Trader trader, Boolean boughtOrsold, Timestamp from, Timestamp to,
+            AsyncCallback<List<Trade>> callback);
+
+    void login(String trader, AsyncCallback<Trader> callback);
+
+    void matchAsk(Ask ask, AsyncCallback<List<Match>> callback);
+
+    void matchBid(Bid bid, AsyncCallback<List<Match>> callback);
+
+    void trade(Match match, AsyncCallback<Trade> callback);
+    
+    void getLog(AsyncCallback<List<LogStatement>> callback);
+
+    void withdraw(Tradable t, AsyncCallback<Tradable> callback);
+    
+    void refresh(Tradable t, AsyncCallback<Tradable> callback);
+}

Propchange: openjpa/trunk/openjpa-examples/opentrader/src/main/java/org/apache/openjpa/trader/client/TradingServiceAdapterAsync.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message