TSA HTML/JS page for OSL league
diff --git a/MySports App/WebContent/tsa/data/root b/MySports App/WebContent/tsa/data/root
deleted file mode 100644
index 1ee320b..0000000
--- a/MySports App/WebContent/tsa/data/root
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-	"name": "Ottawa Scoocer League",
-	"id": "root",
-	"children": [
-		{
-			"name": "Under 6",
-			"id": "u6",
-			"children": true
-		},
-		{
-			"name": "Under 8",
-			"id": "u8",
-			"children": true
-		}
-	]
-}
\ No newline at end of file
diff --git a/MySports App/WebContent/tsa/data/u6 b/MySports App/WebContent/tsa/data/u6
deleted file mode 100644
index c8e941a..0000000
--- a/MySports App/WebContent/tsa/data/u6
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-	"name": "Under 6",
-	"id": "u6",
-	"children": [
-		{
-			"name": "Scorpions",
-			"id": "scorpions"
-		},
-		{
-			"name": "Bears",
-			"id": "bears"
-		},
-		{
-			"name": "Dragons",
-			"id": "dragons"
-		},
-		{
-			"name": "Gorillas",
-			"id": "gorillas"
-		},
-		{
-			"name": "Peaches",
-			"id": "peaches"
-		}
-	]
-}
\ No newline at end of file
diff --git a/MySports App/WebContent/tsa/data/u8 b/MySports App/WebContent/tsa/data/u8
deleted file mode 100644
index 3d8c2b2..0000000
--- a/MySports App/WebContent/tsa/data/u8
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-	"name": "Under 8",
-	"id": "u8",
-	"children": [
-		{
-			"name": "Blazers",
-			"id": "blazers"
-		},
-		{
-			"name": "Gladiators",
-			"id": "gladiators"
-		},
-		{
-			"name": "Ducks",
-			"id": "ducks"
-		},
-		{
-			"name": "Pirates",
-			"id": "pirates"
-		},
-		{
-			"name": "Crusaders",
-			"id": "crusaders"
-		}
-	]
-}
\ No newline at end of file
diff --git a/MySports App/WebContent/tsa/division-teams-tree.js b/MySports App/WebContent/tsa/division-teams-tree.js
deleted file mode 100644
index 58a481f..0000000
--- a/MySports App/WebContent/tsa/division-teams-tree.js
+++ /dev/null
@@ -1,117 +0,0 @@
-	dojo.require("dojo.store.JsonRest");
-	dojo.require("dojo.store.Observable");
-	dojo.require("dijit.Tree");
-	dojo.require("dijit.tree.dndSource");
-	
-	dojo.ready(function() {
-				divisions = dojo.store
-						.JsonRest({
-							target : "data/",
-							mayHaveChildren : function(object) {
-								// see if it has a children property
-								return "children" in object;
-							},
-							getChildren : function(object, onComplete, onError) {
-								// retrieve the full copy of the object
-								this.get(object.id).then(function(fullObject) {
-									// copy to the original object so it has the children array as well.
-									object.children = fullObject.children;
-									// now that full object, we should have an array of children
-									onComplete(fullObject.children);
-								}, function(error) {
-									// an error occurred, log it, and indicate no children
-									console.error(error);
-									onComplete([]);
-								});
-							},
-							getRoot : function(onItem, onError) {
-								// get the root object, we will do a get() and callback the result
-								this.get("root").then(onItem, onError);
-							},
-							getLabel : function(object) {
-								// just get the name
-								return object.name;
-							},
-
-							pasteItem : function(child, oldParent, newParent,
-									bCopy, insertIndex) {
-								var store = this;
-								store
-										.get(oldParent.id)
-										.then(
-												function(oldParent) {
-													store
-															.get(newParent.id)
-															.then(
-																	function(
-																			newParent) {
-																		var oldChildren = oldParent.children;
-																		dojo
-																				.some(
-																						oldChildren,
-																						function(
-																								oldChild,
-																								i) {
-																							if (oldChild.id == child.id) {
-																								oldChildren
-																										.splice(
-																												i,
-																												1);
-																								return true; // done
-																							}
-																						});
-																		store
-																				.put(oldParent);
-																		newParent.children
-																				.splice(
-																						insertIndex || 0,
-																						0,
-																						child);
-																		store
-																				.put(newParent);
-																	},
-																	function(
-																			error) {
-																		alert("Error occurred (this demo is not hooked up to a real database, so this is expected): "
-																				+ error);
-																	});
-												});
-							},
-							put : function(object, options) {
-								//this.onChange(object);
-								this.onChildrenChange(object, object.children);
-								this.onChange(object);
-								return dojo.store.JsonRest.prototype.put.apply(
-										this, arguments);
-							}
-						});
-				tree = new dijit.Tree({
-					model : divisions,
-					dndController : dijit.tree.dndSource,
-					showRoot : false
-				}, "tree"); // make sure you have a target HTML element with this id
-				tree.startup();
-				dojo.query("#add-new-child").onclick(
-						function() {
-							var selectedObject = tree.get("selectedItems")[0];
-							if (!selectedObject) {
-								return alert("No object selected");
-							}
-							divisions.get(selectedObject.id).then(
-									function(selectedObject) {
-										selectedObject.children.push({
-											name : "New child",
-											id : Math.random()
-										});
-										divisions.put(selectedObject);
-									});
-
-						});
-				dojo
-						.connect(
-								tree,
-								"onClick",
-								function(object) {
-									document.getElementById("team-name-header").innerHTML = object.name;
-								});
-			});
\ No newline at end of file
diff --git a/MySports App/WebContent/tsa/index.html b/MySports App/WebContent/tsa/index.html
index 0d0278e..8c7f7e1 100644
--- a/MySports App/WebContent/tsa/index.html
+++ b/MySports App/WebContent/tsa/index.html
@@ -1,53 +1,43 @@
-<!DOCTYPE HTML>
-<html lang="en">
+<!--
+ Copyright 2012, Oracle and or its affiliates. All Rights Reserved.
+ @author irfan.ahmed@oracle.com
+-->
+<!DOCTYPE html>
+<html>
 <head>
-<meta charset="utf-8">
-<title>MySports: DataGrid</title>
-<link rel="stylesheet"
-	href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/resources/dojo.css">
-<link rel="stylesheet"
-	href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/claro.css">
-<link rel="stylesheet"
-	href="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojox/grid/resources/claroGrid.css">
-
-<script
-	src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"
-	data-dojo-config="isDebug: true,parseOnLoad: true">
-	
+<title>My Sports</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link href="/dojo/1.7.2/dijit/themes/claro/claro.css" rel="stylesheet" />
+<link href="lib/demo/demo.css" rel="stylesheet" />
+<script>
+	djConfig = {
+		isDebug : false,
+		parseOnLoad : true
+	}
 </script>
-<script type="text/javascript" src="division-teams-tree.js"/>
+<script src="/dojo/1.7.2/dojo/dojo.js"></script>
+<script src="lib/demo/demo.js"></script>
+<script>
+	dojo.addOnLoad(function() {
+		console.debug("Dojo Loaded: ", dojo.version);
+		demoApp = {
+			utils : new demo.Utils(),
+			navPanel : new demo.NavPanel()
+		}
+		demoApp.navPanel.init();
+	});
+</script>
 </head>
 <body class="claro">
-	<table width="100%" cellpadding="20" cellspacing="20">
-		<tr>
-			<td><img src="../images/mysports.png"></td>
-			<td width="100%" align="right">User: <input name="login"
-				type="text"> Password: <input name="login" type="text">
-			<button id="login hidden="true">Login</button>
-			</td>
-		</tr>
-
-
-		<tr>
-			<td colspan="2" valign="top">
-				<h1>MySports: Ottawa Soccer League</h1>
-			</td>
-		</tr>
-
-		<tr>
-			<td height="500" width="150" valign="top">
-				<h2>Divisions</h2>
-					<button id="add-new-child">Add</button>
-				<div id="tree" />
-			</td>
-
-			<td valign="middle" align="left" width="100%">
-				<h2 id="team-name-header">&nbsp;</h2>
-				<div id="team-grid" />
-			</td>
-		</tr>
-	</table>
-
-
+	<div class="mainContainer">
+		<div class="masthead"><img src="/MySportsAdmin/rest/league/OSL.png" /></div>
+		<div class="navigation">
+			<div id="tree"></div>
+		</div>
+		<div class="content">
+			
+			<div id="playersTableDiv"></div>
+		</div>
+	</div>
 </body>
 </html>
diff --git a/MySports App/WebContent/tsa/lib/demo/demo.css b/MySports App/WebContent/tsa/lib/demo/demo.css
new file mode 100644
index 0000000..915a001
--- /dev/null
+++ b/MySports App/WebContent/tsa/lib/demo/demo.css
@@ -0,0 +1,76 @@
+/* 
+    Document   : demo
+    Created on : 7 Jun, 2012, 2:04:42 AM
+    Author     : irfan.ahmed@oracle.com
+    Description:
+        Purpose of the stylesheet follows.
+*/
+
+body {
+    font-size: 12px;
+    color: #333;
+    font-family: Ubuntu, Tahoma, Helvetica,Verdana,Arial,sans-serif;
+}
+
+.mainContainer {
+}
+
+.mainContainer .navigation {
+    position: absolute;
+    top: 150px;
+    left: 0;
+    width: 250px;
+    bottom: 0;
+}
+
+.mainContainer .content {
+    position: absolute;
+    left: 251px;
+    right: 0;
+    top: 150px;
+    bottom: 0;
+    background-color: #fdfdfd;
+}
+
+#playersTableDiv {
+    border: 1px solid #CCCCCC;
+    border-radius: 4px 4px 4px 4px;
+    margin: 20px;
+    padding: 5px;
+    background: #f0f0f0;
+}
+
+#playersTableDiv table {
+    width: 100%;
+    font-size: 11px;
+    background: #fff;
+}
+
+#playersTableDiv table th, #playersTableDiv table td {
+    border-color: #CCCCCC;
+    padding: 2px 5px;
+}
+
+#playersTableDiv table th {
+    color: #666666;
+    text-transform: uppercase;
+}
+
+#playersTableDiv table td {
+    
+}
+
+#playersTableDiv table caption {
+    font-size: 13px;
+    font-weight: bold;
+    padding: 0 0 4px 1px;
+    text-align: left;
+}
+
+.masthead {
+    height: 150px;
+    left: 0;
+    position: absolute;
+    right: 0;
+    top: 0;
+}
\ No newline at end of file
diff --git a/MySports App/WebContent/tsa/lib/demo/demo.js b/MySports App/WebContent/tsa/lib/demo/demo.js
new file mode 100644
index 0000000..9a951ce
--- /dev/null
+++ b/MySports App/WebContent/tsa/lib/demo/demo.js
@@ -0,0 +1,241 @@
+/* 
+ *  Copyright 2012, Oracle and or its affiliates. All Rights Reserved.
+ *  
+ *  @author irfan.ahmed@oracle.com
+ */
+
+dojo.provide("demo.demo");
+
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dojo.data.ObjectStore");
+dojo.require("dijit._Widget");
+dojo.require("dijit.Tree");
+dojo.require("dijit.tree.ForestStoreModel");
+
+
+dojo.declare("demo.Utils", null, {
+    get: function(args) {
+        if(!(args.url && args.onSuccess)) {
+            throw "url/onSuccess parameters are required for XHR Get call.";
+        }
+        dojo.xhrGet({
+            url: args.url,
+            headers : {
+                Accept: "application/json",
+                "Content-Type": "application/json"
+            },
+            handleAs: "json",
+            load: function(data, ioArgs) {
+                args.onSuccess.apply(args.context, [data, ioArgs]);
+            },
+            error: function(error, ioArgs) {
+                console.error("Error occurred: ", error);
+            },
+            timeout: 15000,
+            sync: (args.sync?args.sync:false)
+        });
+    }
+});
+
+dojo.declare("demo.NavPanel", [dijit._Widget], {
+    constructor: function() {
+        this.treeData = {
+            label: "name",
+            identifier: "id",
+            items: []
+        };
+    },
+    
+    init: function() {
+        demoApp.utils.get({
+            url: "/MySports/persistence/mysports-OSL/query/Division.findAll",
+            onSuccess: function(divisions) {
+                this.divisions = divisions;
+                var divLength = this.divisions.length;
+                dojo.forEach(this.divisions, function(division, divIndex) {
+                    division.type = "division";
+                    if(!division.children) {
+                        division.children = [];
+                    }
+                    this.getTeam(division, function() {
+                        console.debug("Loaded Teams for division ", division.id);
+                        this.treeData.items.push(division);
+                        if(divIndex == (divLength -1)) {
+                            this.createTree();
+                        }
+                    });
+                }, this);
+            },
+            context: this
+        });
+    },
+    
+    getTeam: function(division, doneLoadingTeams) {
+        var teams = [];
+        dojo.forEach(division.relationships, function(rel) {
+            if(!rel.id) {
+                rel.id = division.id + "_" + rel.rel;
+            }
+            if(rel.rel == "teams") {
+                teams.push(rel);
+            }
+        });
+        var teamLength = teams.length;
+        dojo.forEach(teams, function(teamInfo, index) {
+            demoApp.utils.get({
+                url: teamInfo.href,
+                onSuccess: function(teamData) {
+                    console.debug("Team Data for divsion : ", division.id, teamData)
+                    dojo.forEach(teamData, function(team) {
+                        team.type = "team";
+                        dojo.forEach(team.relationships, function(teamRel) {
+                            if(!teamRel.id) {
+                                teamRel.id = team.id + "_" + teamRel.rel;
+                            }
+                        });
+                        division.children.push(team);
+                    });
+                    if(index == (teamLength -1)) {
+                        if(doneLoadingTeams) {
+                            doneLoadingTeams.call(this)
+                        }
+                    }
+                },
+                context: this
+            })
+        }, this);
+    },
+    
+    createTree: function() {
+        console.debug("Creating Tree : ", dojo.toJson(this.treeData, "  "));
+        this.treeStore = new dojo.data.ItemFileReadStore({
+            data: this.treeData
+        });
+        this.treeStore.fetch({
+            query:{type:"division"},
+            onItem: function(item) {
+                console.debug(item);
+            },
+            onError: function(error) {
+                console.error(error);
+            }
+        });
+        this.treeModel = new dijit.tree.ForestStoreModel({
+            store: this.treeStore,
+            query: {type: "division"},
+            rootId: "root",
+            rootLabel: "Divisions",
+            childrenAttrs: ["children"]
+        });
+        this.tree = new dijit.Tree({
+            model: this.treeModel
+        }, "tree");
+        this.connect(this.tree, "onClick", function(item) {
+            if(this.treeStore.isItem(item)) {
+                var type = this.treeStore.getValue(item, "type");
+                var name = this.treeStore.getValue(item, "name");
+                if(type == "team") {
+                    var relationShips = this.treeStore.getValues(item, "relationships");
+                    var players = dojo.filter(relationShips, function(rel) {
+                        return this.treeStore.getValue(rel, "rel") == "players";
+                    }, this)[0];
+                    this.showPlayers(name, players);
+                } else if(type == "division") {
+                    this.showDivision(item);
+                }
+            }
+        });
+        this.createPlayersTable();
+    },
+    
+    showPlayers: function(teamName, item) {
+        var href = this.treeStore.getValue(item, "href");
+        console.debug("Showing Players : ", href);
+        demoApp.utils.get({
+            url: href,
+            onSuccess: function(playersInfo) {
+                console.debug("Players : ", playersInfo);
+                this.playersTable.destroyAllRows();
+                this.playersTable.setCaption("Team: " + teamName);
+                dojo.forEach(playersInfo, function(player) {
+                    this.playersTable.addRow(player);
+                }, this);
+            },
+            context: this
+        });
+    },
+    
+    showDivision: function(item) {
+        console.debug("Showing Division : ", item);
+    },
+    
+    createPlayersTable: function() {
+        this.creatingTable = true;
+        demoApp.utils.get({
+            url: "/MySports/persistence/mysports-OSL/metadata/entity/Player",
+            onSuccess: function(tableInfo) {
+                this.playerTableInfo = tableInfo;
+                this.playersTable = new demo.PlayersTable(this.playerTableInfo);
+                dojo.byId("playersTableDiv").appendChild(this.playersTable.domNode);
+                this.creatingTable = false;
+            },
+            context: this
+        });
+    }
+});
+
+dojo.declare("demo.PlayersTable", [dijit._Widget], {
+    constructor: function(args) {
+        this.info = args;
+        this.cols = [];
+        this.rows = [];
+    },
+    
+    postCreate: function() {
+        this.domNode = dojo.create("table", {
+            "class" : "playersTable",
+            border: "1",
+            rules: "all"
+        });
+        this.captionNode = dojo.create("caption", null, this.domNode);
+        this.tableNode = dojo.create("tbody", null, this.domNode);
+        this.createCols();
+    },
+    
+    createCols: function() {
+        var headerRow = dojo.create("tr", null, this.tableNode);
+        dojo.forEach(this.attributes, function(colInfo, index) {
+            this.cols.push(colInfo.name);
+            dojo.create("th", {
+                "class": (index == 0?"first":(index==this.attributes.length-1?"last":"")),
+                innerHTML: colInfo.name
+            }, headerRow)
+        }, this);
+    },
+    
+    setCaption: function(caption) {
+        dojo.attr(this.captionNode, "innerHTML", caption);
+    },
+    
+    addRow: function(rowInfo) {
+        console.debug("Adding : ", rowInfo);
+        var row = dojo.create("tr", null, this.tableNode);
+        dojo.forEach(this.cols, function(name) {
+            dojo.create("td", {
+                innerHTML: (rowInfo[name]?rowInfo[name]:"")
+            }, row);
+        });
+        this.rows.push(row);
+    },
+    
+    destroyAllRows: function() {
+        dojo.forEach(this.rows, function(row) {
+            dojo.destroy(row);
+        })
+    }
+})
+
+
+
+
+
diff --git a/MySports App/WebContent/tsa/players-grid.js b/MySports App/WebContent/tsa/players-grid.js
deleted file mode 100644
index d98f91d..0000000
--- a/MySports App/WebContent/tsa/players-grid.js
+++ /dev/null
@@ -1,59 +0,0 @@
-dojo.require("dojox/grid/DataGrid");
-dojo.require("dojo/store/Memory");
-dojo.require("dojo/data/ObjectStore");
-dojo.require("dojo/_base/xhr");
-dojo.require("dojo/domReady!");
-
-var grid, store, dataStore;
-
-dojo
-		.ready(
-
-		function(DataGrid, Memory, ObjectStore, xhr) {
-			xhr
-					.get(
-							{
-								url : "http://localhost:8080/MySports/persistence/mysports-OSL/query/Player.findAll",
-								handleAs : "json",
-								headers : {
-									"Accept" : "application/json"
-								},
-								contentType : "application/json"
-							}).then(function(data) {
-
-						store = new Memory({
-							data : data
-						});
-						dataStore = new ObjectStore({
-							objectStore : store
-						});
-
-						grid = new DataGrid({
-							store : dataStore,
-							query : {
-								id : "*"
-							},
-							structure : [ {
-								cells : [ {
-									name : "ID",
-									field : "id"
-								}, {
-									name : "First Name",
-									field : "firstName"
-								}, {
-									name : "Last Name",
-									field : "lastName"
-								}, {
-									name : "Number",
-									field : "number"
-								} ]
-							} ]
-						}, "grid");
-
-						// since we created this grid programmatically, call
-						// startup to
-						// render
-						// it
-						grid.startup();
-					});
-		});
diff --git a/MySports App/src/example/mysports/model/MOXyHelper.java b/MySports App/src/example/mysports/model/MOXyHelper.java
new file mode 100644
index 0000000..67fefb1
--- /dev/null
+++ b/MySports App/src/example/mysports/model/MOXyHelper.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2012 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the 
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
+ * which accompanies this distribution. 
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at 
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *  dclarke - EclipseLink 2.4 - MySports Demo Bug 344608
+ ******************************************************************************/
+package example.mysports.model;
+
+import static org.eclipse.persistence.jaxb.MarshallerProperties.MEDIA_TYPE;
+import static org.eclipse.persistence.jaxb.UnmarshallerProperties.JSON_INCLUDE_ROOT;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.oxm.MediaType;
+
+public class MOXyHelper {
+
+    private static JAXBContext context;
+
+    public static JAXBContext getContext() throws JAXBException {
+        if (context == null) {
+            context = JAXBContextFactory.createContext(new Class[] { Division.class, Team.class, Player.class }, null);
+        }
+        return context;
+    }
+
+    public static Marshaller createMarshaller(MediaType mediaType) throws JAXBException {
+        Marshaller marshaller = getContext().createMarshaller();
+        marshaller.setProperty(MEDIA_TYPE, mediaType.getMediaType());
+        return marshaller;
+    }
+
+    public static Unmarshaller createUnmarshaller(MediaType mediaType) throws JAXBException {
+        Unmarshaller unmarshaller = getContext().createUnmarshaller();
+        unmarshaller.setProperty(MEDIA_TYPE, mediaType.getMediaType());
+        unmarshaller.setProperty(JSON_INCLUDE_ROOT, false);
+        return unmarshaller;
+    }
+
+}