You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by hn...@apache.org on 2010/10/29 17:34:41 UTC

svn commit: r1028804 [1/2] - in /shindig/sandbox/trunk/cmis-binding: ./ config/ content/ content/container/ content/samplecontainer/ content/samplecontainer/examples/ content/samplecontainer/examples/media/ src/ src/main/ src/main/java/ src/main/java/o...

Author: hnguy
Date: Fri Oct 29 15:34:40 2010
New Revision: 1028804

URL: http://svn.apache.org/viewvc?rev=1028804&view=rev
Log:
SHINDIG-1451 | From Eric Woods | Maven Project for CMIS Binding of Albums & MediaItems Services

Added:
    shindig/sandbox/trunk/cmis-binding/README.txt
    shindig/sandbox/trunk/cmis-binding/config/
    shindig/sandbox/trunk/cmis-binding/config/container.js
    shindig/sandbox/trunk/cmis-binding/content/
    shindig/sandbox/trunk/cmis-binding/content/container/
    shindig/sandbox/trunk/cmis-binding/content/container/gadgets.css
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Media.xml
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/MediaUI.js
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Social.js
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/styles.css
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.html
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.js
    shindig/sandbox/trunk/cmis-binding/content/samplecontainer/state.dtd
    shindig/sandbox/trunk/cmis-binding/pom.xml
    shindig/sandbox/trunk/cmis-binding/src/
    shindig/sandbox/trunk/cmis-binding/src/main/
    shindig/sandbox/trunk/cmis-binding/src/main/java/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/CMISGuiceModule.java
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/sample/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/sample/CMISService.java
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/utils/
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/utils/CMISNotifier.java
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/utils/CMISUtil.java
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/utils/CMISWrapper.java
    shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/utils/RepoUtil.java
    shindig/sandbox/trunk/cmis-binding/src/main/webapp/
    shindig/sandbox/trunk/cmis-binding/src/main/webapp/WEB-INF/
    shindig/sandbox/trunk/cmis-binding/src/main/webapp/WEB-INF/web.xml
Modified:
    shindig/sandbox/trunk/cmis-binding/   (props changed)

Propchange: shindig/sandbox/trunk/cmis-binding/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Oct 29 15:34:40 2010
@@ -0,0 +1,4 @@
+.settings
+.classpath
+.project
+target

Added: shindig/sandbox/trunk/cmis-binding/README.txt
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/README.txt?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/README.txt (added)
+++ shindig/sandbox/trunk/cmis-binding/README.txt Fri Oct 29 15:34:40 2010
@@ -0,0 +1,29 @@
+===========================================================================
+README - CONFIGURING CMIS BINDING FOR APACHE SHINDIG'S ALBUMS & MEDIAITEMS
+===========================================================================
+
+Author: Eric Woods
+Email: woodstae@gmail.com
+Date: 26 October 2010
+
+INTRODUCTION
+This project uses CMIS as the back-end for the Albums & MediaItems services in Apache Shindig.  CMIS Folders & Documents are mapped to OpenSocial Albums & MediaItems, respectively.  This project is intended to be commmitted to Shindig's sandbox directory for the community to explore.
+
+APPLY CMIS CONFIGURATION PATCH
+1) Download and build Shindig trunk
+	a) SVN: https://svn.apache.org/repos/asf/shindig/trunk
+	b) Maven build...
+2) Download and build this project (cmis-binding)
+	a) https://svn.apache.org/repos/asf/shindig/sandbox
+	b) Maven build...
+3) Verify that the configuration is correct
+	a) Deploy CMIS WAR file using your favorite application server
+	b) Access samplecontainer (e.g. http://localhost:8080/samplecontainer/samplecontainer.html)
+	c) Point samplecontainer to the included sample Media gadget (e.g. http://localhost:8080/samplecontainer/examples/media/Media.xml)
+	d) You should see your CMIS Folders & Documents displayed as OpenSocial Albums & MediaItems
+
+CONFIGURE CMIS REPOSITORY SETTINGS
+Set your desired repository & root path
+	a) navigate to src/main/java/org/apache/shindig/extras/cmis/sample/CMISService.java
+	b) Set the CMIS_REPO variable to a repository of your choice (currently does not support authentication)
+	c) Set the ROOT_PATH variable to the path of your desired root folder
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/config/container.js
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/config/container.js?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/config/container.js (added)
+++ shindig/sandbox/trunk/cmis-binding/config/container.js Fri Oct 29 15:34:40 2010
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+// Default container configuration. To change the configuration, you have two options:
+//
+// A. If you run the Java server: Create your own "myContainer.js" file and
+// modify the value in web.xml.
+//
+//  B. If you run the PHP server: Create a myContainer.js, copy the contents of container.js to it,
+//  change
+//		{"gadgets.container" : ["default"],
+//  to
+//		{"gadgets.container" : ["myContainer"],
+// And make your changes that you need to myContainer.js.
+// Just make sure on the iframe URL you specify &container=myContainer
+// for it to use that config.
+//
+// All configurations will automatically inherit values from this
+// config, so you only need to provide configuration for items
+// that you require explicit special casing for.
+//
+// Please namespace your attributes using the same conventions
+// as you would for javascript objects, e.g. gadgets.features
+// rather than "features".
+
+// NOTE: Please _don't_ leave trailing commas because the php json parser
+// errors out on this.
+
+// Container must be an array; this allows multiple containers
+// to share configuration.
+// TODO: Move out accel container config into a separate accel.js file.
+{"gadgets.container" : ["default", "accel"],
+
+// Set of regular expressions to validate the parent parameter. This is
+// necessary to support situations where you want a single container to support
+// multiple possible host names (such as for localized domains, such as
+// <language>.example.org. If left as null, the parent parameter will be
+// ignored; otherwise, any requests that do not include a parent
+// value matching this set will return a 404 error.
+"gadgets.parent" : null,
+
+// Should all gadgets be forced on to a locked domain?
+"gadgets.lockedDomainRequired" : false,
+
+// DNS domain on which gadgets should render.
+"gadgets.lockedDomainSuffix" : "-a.example.com:8080",
+	
+// Origins for CORS requests and/or Referer validation
+// Indicate a set of origins or an entry with * to indicate that all origins are allowed
+"gadgets.parentOrigins" : ["*"],
+
+// Various urls generated throughout the code base.
+// iframeBaseUri will automatically have the host inserted
+// if locked domain is enabled and the implementation supports it.
+// query parameters will be added.
+"gadgets.iframeBaseUri" : "/gadgets/ifr",
+"gadgets.uri.iframe.basePath" : "/gadgets/ifr",
+
+// jsUriTemplate will have %host% and %js% substituted.
+// No locked domain special cases, but jsUriTemplate must
+// never conflict with a lockedDomainSuffix.
+"gadgets.jsUriTemplate" : "http://%host%/gadgets/js/%js%",
+
+//New configuration for iframeUri generation:
+"gadgets.uri.iframe.lockedDomainSuffix" :  "-a.example.com:8080",
+"gadgets.uri.iframe.unlockedDomain" : "www.example.com:8080",
+"gadgets.uri.iframe.basePath" : "/gadgets/ifr",
+
+"gadgets.uri.js.host" : "http://www.example.com/",
+"gadgets.uri.js.path" : "/gadgets/js",
+	
+	
+// Callback URL.  Scheme relative URL for easy switch between https/http.
+"gadgets.oauthGadgetCallbackTemplate" : "//%host%/gadgets/oauthcallback",
+
+// Use an insecure security token by default
+"gadgets.securityTokenType" : "insecure",
+
+// Config param to load Opensocial data for social
+// preloads in data pipelining.  %host% will be
+// substituted with the current host.
+"gadgets.osDataUri" : "http://%host%/rpc",
+
+// Uncomment these to switch to a secure version
+//
+//"gadgets.securityTokenType" : "secure",
+//"gadgets.securityTokenKeyFile" : "/path/to/key/file.txt",
+
+// URI for the default shindig test instance.
+"defaultShindigTestHost": "http://${SERVER_HOST}:${SERVER_PORT}",
+
+// Authority (host:port without scheme) for the proxy and concat servlets.
+"defaultShindigProxyConcatAuthority": "${SERVER_HOST}:${SERVER_PORT}",
+
+// Default Uri config: these must be overridden - specified here for testing purposes
+"gadgets.uri.iframe.unlockedDomain": "${Cur['defaultShindigTestHost']}",
+"gadgets.uri.iframe.lockedDomainSuffix": "${Cur['defaultShindigTestHost']}",
+
+// Default Js Uri config: also must be overridden.
+"gadgets.uri.js.host": "${Cur['defaultShindigTestHost']}",
+"gadgets.uri.js.path": "/gadgets/js",
+
+// Default concat Uri config; used for testing.
+"gadgets.uri.concat.host" : "${Cur['defaultShindigProxyConcatAuthority']}",
+"gadgets.uri.concat.path" : "/gadgets/concat",
+"gadgets.uri.concat.js.splitToken" : "false",
+
+// Default proxy Uri config; used for testing.
+"gadgets.uri.proxy.host" : "${Cur['defaultShindigProxyConcatAuthority']}",
+"gadgets.uri.proxy.path" : "/gadgets/proxy",
+
+// This config data will be passed down to javascript. Please
+// configure your object using the feature name rather than
+// the javascript name.
+
+// Only configuration for required features will be used.
+// See individual feature.xml files for configuration details.
+"gadgets.features" : {
+  "core.io" : {
+    // Note: /proxy is an open proxy. Be careful how you expose this!
+    // Note: Here // is replaced with the current protocol http/https
+    "proxyUrl" : "//%host%/gadgets/proxy?container=default&refresh=%refresh%&url=%url%%rewriteMime%",
+    "jsonProxyUrl" : "//%host%/gadgets/makeRequest"
+  },
+  "views" : {
+    "profile" : {
+      "isOnlyVisible" : false,
+      "urlTemplate" : "http://localhost/gadgets/profile?{var}",
+      "aliases": ["DASHBOARD", "default"]
+    },
+    "canvas" : {
+      "isOnlyVisible" : true,
+      "urlTemplate" : "http://localhost/gadgets/canvas?{var}",
+      "aliases" : ["FULL_PAGE"]
+    }
+  },
+  "tabs": {
+    "css" : [
+      ".tablib_table {",
+      "width: 100%;",
+      "border-collapse: separate;",
+      "border-spacing: 0px;",
+      "empty-cells: show;",
+      "font-size: 11px;",
+      "text-align: center;",
+    "}",
+    ".tablib_emptyTab {",
+      "border-bottom: 1px solid #676767;",
+      "padding: 0px 1px;",
+    "}",
+    ".tablib_spacerTab {",
+      "border-bottom: 1px solid #676767;",
+      "padding: 0px 1px;",
+      "width: 1px;",
+    "}",
+    ".tablib_selected {",
+      "padding: 2px;",
+      "background-color: #ffffff;",
+      "border: 1px solid #676767;",
+      "border-bottom-width: 0px;",
+      "color: #3366cc;",
+      "font-weight: bold;",
+      "width: 80px;",
+      "cursor: default;",
+    "}",
+    ".tablib_unselected {",
+      "padding: 2px;",
+      "background-color: #dddddd;",
+      "border: 1px solid #aaaaaa;",
+      "border-bottom-color: #676767;",
+      "color: #000000;",
+      "width: 80px;",
+      "cursor: pointer;",
+    "}",
+    ".tablib_navContainer {",
+      "width: 10px;",
+      "vertical-align: middle;",
+    "}",
+    ".tablib_navContainer a:link, ",
+    ".tablib_navContainer a:visited, ",
+    ".tablib_navContainer a:hover {",
+      "color: #3366aa;",
+      "text-decoration: none;",
+    "}"
+    ]
+  },
+  "minimessage": {
+      "css": [
+        ".mmlib_table {",
+        "width: 100%;",
+        "font: bold 9px arial,sans-serif;",
+        "background-color: #fff4c2;",
+        "border-collapse: separate;",
+        "border-spacing: 0px;",
+        "padding: 1px 0px;",
+      "}",
+      ".mmlib_xlink {",
+        "font: normal 1.1em arial,sans-serif;",
+        "font-weight: bold;",
+        "color: #0000cc;",
+        "cursor: pointer;",
+      "}"
+     ]
+  },
+  "rpc" : {
+    // Path to the relay file. Automatically appended to the parent
+    // parameter if it passes input validation and is not null.
+    // This should never be on the same host in a production environment!
+    // Only use this for TESTING!
+    "parentRelayUrl" : "/container/rpc_relay.html",
+
+    // If true, this will use the legacy ifpc wire format when making rpc
+    // requests.
+    "useLegacyProtocol" : false
+  },
+  // Skin defaults
+  "skins" : {
+    "properties" : {
+      "BG_COLOR": "",
+      "BG_IMAGE": "",
+      "BG_POSITION": "",
+      "BG_REPEAT": "",
+      "FONT_COLOR": "",
+      "ANCHOR_COLOR": ""
+    }
+  },
+  "opensocial" : {
+    // Path to fetch opensocial data from
+    // Must be on the same domain as the gadget rendering server
+    "path" : "http://%host%/rpc",
+    // Path to issue invalidate calls
+    "invalidatePath" : "http://%host%/rpc",
+    "domain" : "shindig",
+    "enableCaja" : false,
+    "supportedFields" : {
+       "person" : ["id", {"name" : ["familyName", "givenName", "unstructured"]}, "thumbnailUrl", "profileUrl"],
+       "activity" : ["appId", "body", "bodyId", "externalId", "id", "mediaItems", "postedTime", "priority", 
+                     "streamFaviconUrl", "streamSourceUrl", "streamTitle", "streamUrl", "templateParams", "title",
+                     "url", "userId"],
+       "album" : ["id", "thumbnailUrl", "title", "description", "location", "ownerId"],
+       "mediaItem" : ["album_id", "created", "description", "duration", "file_size", "id", "language", "last_updated",
+                      "location", "mime_type", "num_comments", "num_views", "num_votes", "rating", "start_time",
+                      "tagged_people", "tags", "thumbnail_url", "title", "type", "url"]
+    }
+  },
+  "osapi.services" : {
+    // Specifying a binding to "container.listMethods" instructs osapi to dynamicaly introspect the services
+    // provided by the container and delay the gadget onLoad handler until that introspection is
+    // complete.
+    // Alternatively a container can directly configure services here rather than having them
+    // introspected. Simply list out the available servies and omit "container.listMethods" to
+    // avoid the initialization delay caused by gadgets.rpc
+    // E.g. "gadgets.rpc" : ["activities.requestCreate", "messages.requestSend", "requestShareApp", "requestPermission"]
+    "gadgets.rpc" : ["container.listMethods"]
+  },
+  "osapi" : {
+    // The endpoints to query for available JSONRPC/REST services
+    "endPoints" : [ "http://%host%/rpc" ]
+  },
+  "osml": {
+    // OSML library resource.  Can be set to null or the empty string to disable OSML
+    // for a container.
+    "library": "config/OSML_library.xml"
+  }
+}}

Added: shindig/sandbox/trunk/cmis-binding/content/container/gadgets.css
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/container/gadgets.css?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/container/gadgets.css (added)
+++ shindig/sandbox/trunk/cmis-binding/content/container/gadgets.css Fri Oct 29 15:34:40 2010
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+ 
+.gadgets-gadget-chrome {
+  float: left;
+  margin: 4px;
+  border: 1px solid #7aa5d6;
+}
+
+.gadgets-gadget {
+  border: none;
+}
+
+.gadgets-gadget-title-bar {
+  padding: 2px 4px;
+  background-color: #e5ecf9;
+}
+
+.gadgets-gadget-title {
+  font-weight: bold;
+  color: #3366cc;
+}
+
+.gadgets-gadget-title-button-bar {
+  font-size: smaller;
+}
+
+.gadgets-gadget-user-prefs-dialog {
+  background-color: #e5ecf9;
+}
+
+.gadgets-gadget-user-prefs-dialog-action-bar {
+  text-align: center;
+  padding-bottom: 4px;
+}
+
+.gadgets-gadget-title-button {
+}
+
+.gadgets-gadget-content {
+  padding: 4px;
+}
+
+.gadgets-log-entry {
+}
+
+// Used to style messages produced during rewriting by CajaContentRewriter
+.gadgets-messages {
+	
+}

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Media.xml
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Media.xml?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Media.xml (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Media.xml Fri Oct 29 15:34:40 2010
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<Module>
+    <ModulePrefs title="Albums and MediaItems">
+        <Require feature="osapi"/>
+        <Require feature="dynamic-height"/>
+    </ModulePrefs>
+    
+    <Content type="html"><![CDATA[
+    <html>
+        <head>	
+            <!-- Source imports -->
+            <script src='http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js' type='text/javascript' djConfig='parseOnLoad:true, isDebug:true'></script>
+            <script src='Social.js' type='text/javascript'></script>
+            <script src='MediaUI.js' type='text/javascript'></script>
+            
+            
+            <!-- Styling -->
+            <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/tundra/tundra.css"></link>
+            <link rel="stylesheet" type="text/css" href="styles.css">
+            <style type="text/css">
+            </style>
+            
+            <!-- DOJO requires -->
+            <script type='text/javascript'>
+                dojo.require('dijit.form.Button');
+                dojo.require('dijit.form.Form');
+                dojo.require('dijit.form.TextBox');
+                dojo.require('dijit.form.ValidationTextBox');
+                dojo.require('dijit.Dialog');
+                dojo.require('dijit.form.Textarea');
+                dojo.require('dijit.layout.ContentPane');
+                dojo.require('dijit.layout.TabContainer');
+            </script>
+            
+            <!-- JavaScript -->
+            <script type="text/javascript"> 
+                <!-- Entry point to the gadget -->
+                function init() {
+                    console.log("dojo initialized");
+                    new MediaUI(new SocialWrapper()).init();
+                }
+            
+                <!-- Register entry point -->
+                dojo.addOnLoad(init);   // TODO: work-around to tundra.css issue
+                //gadgets.util.registerOnLoadHandler(function() {
+                    //dojo.addOnLoad(init);
+                //});     
+            </script>   
+        </head>
+        <body class="tundra">
+        </body>
+    </html>
+    ]]></Content>
+</Module>
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/MediaUI.js
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/MediaUI.js?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/MediaUI.js (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/MediaUI.js Fri Oct 29 15:34:40 2010
@@ -0,0 +1,524 @@
+/**
+ * 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.
+ */
+
+/*
+ * The User Interface for the Albums & MediaItems gadget.
+ *
+ * SHINDIG TODOS
+ *  set ownerId automatically?
+ *  delete children mediaitems when album deleted?
+ *  update only updates given fields?
+ *  update album mediaitem count when inserting/removing mediaitem?
+ *
+ * GADGET TODOS
+ *  album info such as how many albums are contained
+ *  fix auto height for edit album popup
+ *  thumnail pictures
+ */
+function MediaUI(social) {
+    var viewer = null;
+    var divManager = null;
+    
+    var folderUrl = "http://www.clker.com/cliparts/2/b/b/3/1194983972976950993blue_folder_seth_yastrov_01.svg.med.png";
+    var docUrl = "http://www.plastyc.com/images/document-icon.png";
+    
+    /*
+     * Initializes the gadget.
+     */
+    this.init = function() {
+        console.log("initializing AlbumsUI");
+        
+        // Manages high-level divs
+        divManager = new DivManager();
+        divManager.init();
+        
+        // Load data and render
+        loadData(function() {
+            social.getAlbumsByUser(viewer.id, function(response) {
+                renderAlbums(response.list);
+                divManager.showAlbums();
+            });
+        });
+    }
+    
+    /*
+     * Pre-load data for gadget.
+     */
+    function loadData(callback) {
+        social.getViewer(function(data) {
+            viewer = data;
+            callback();
+        });
+    }
+    
+    /*
+     * Manages the gadgets main DIV elements.
+     * 
+     * TODO: use dojo.query() & classes rather than divs[]
+     * TODO: showOnly() function to avoid flashing/pauses
+     */
+    function DivManager() {
+        var divs = [];
+    
+        this.init = function() {
+            console.log('DivManager.init');
+            addDiv('albumsDiv');
+            addDiv('mediaItemsDiv');
+            addDiv('mediaItemDiv');
+            hideAll();
+        }
+    
+        this.showAlbums = function() {
+            console.log('DivManager.showAlbums');
+            hideAll();
+            divs['albumsDiv'].style.display = 'block';
+            this.refreshWindow();
+        }
+        
+        this.showMediaItems = function() {
+            console.log('DivManager.showMediaItems');
+            hideAll();
+            divs['mediaItemsDiv'].style.display = 'block';
+            this.refreshWindow();
+        }
+        
+        this.showMediaItem = function() {
+            console.log('DivManager.showMediaItem');
+            hideAll();
+            divs['mediaItemDiv'].style.display = 'block';
+            this.refreshWindow();
+        }
+        
+        this.refreshWindow = function() {
+            gadgets.window.adjustHeight(500);
+        }
+        
+        function hideAll() {
+            for (key in divs) { divs[key].style.display = 'none'; }
+        }
+        
+        function addDiv(id) { divs[id] = dojo.create('div', {id: id}, dojo.body()); }
+    }
+    
+    /*
+     * Renders a list of the given albums.
+     */
+    function renderAlbums(albums) {
+        console.log('renderAlbums');
+
+        dojo.empty('albumsDiv');
+        var albumsDiv = dojo.byId('albumsDiv');
+        
+        var albumsBanner = dojo.create('div', null, albumsDiv);
+        var table = dojo.create('table', null, albumsBanner);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        dojo.create('td', {innerHTML: viewer.name.formatted + "'s Albums", className: 'albumsTitle'}, tr);
+        dojo.create('td', null, tr).appendChild(new dijit.form.Button({label: '+ New Album', onClick: dojo.hitch(this, editAlbumPopup, null)}).domNode);
+        
+        var albumsList = dojo.create('div', null, albumsDiv);
+        if (albums.length > 0) {
+            var table = dojo.create('table', {className: 'albumsTable'}, albumsList);
+            var tbody = dojo.create('tbody', null, table);
+            for (i = 0; i < albums.length; i++) {
+                var albumRow = dojo.create('tr', null, tbody);
+                var albumLeft = dojo.create('td', {className: 'albumListThumbnail'}, albumRow);
+                var imgLink = dojo.create('a', {href: "javascript:;", onclick: dojo.hitch(this, onClickAlbum, viewer.id, albums[i])}, albumLeft);
+                dojo.create('img', {src: albums[i].thumbnailUrl, onerror: "this.src='" + folderUrl + "';", width: '100%'}, imgLink);
+                var albumRight = dojo.create('td', {className: 'albumListRight'}, albumRow);
+                var albumTitleRow = dojo.create('tr', null, albumRight);
+                var titleTd = dojo.create('td', {className: 'albumListTitle'}, albumTitleRow); 
+                dojo.create('a', {innerHTML: albums[i].title, href: 'javascript:;', onclick: dojo.hitch(this, onClickAlbum, viewer.id, albums[i])}, titleTd);
+                var editTd = dojo.create('td', {className: 'actionLinks', style: 'text-align: right'}, albumTitleRow);
+                dojo.create('a', {innerHTML: 'edit', href: 'javascript:;', onclick: dojo.hitch(this, editAlbumPopup, albums[i])}, editTd);
+                editTd.appendChild(dojo.doc.createTextNode(' | '));
+                dojo.create('a', {innerHTML: 'delete', href: 'javascript:;', onclick: dojo.hitch(this, deleteAlbumPopup, albums[i])}, editTd);
+                if (albums[i].description) {
+                    var albumDescription = dojo.create('tr', null, albumRight);
+                    dojo.create('td', {innerHTML: albums[i].description, className: 'albumListDescription', colspan: '2'}, albumDescription);
+                }
+                //var albumInfo = dojo.create('tr', null, albumRight);
+                //var infoStr = "ID: " + albums[i].id + " | Owner ID: " + albums[i].ownerId;
+                //dojo.create('td', {innerHTML: infoStr, className: 'albumListInfo', colspan: '2'}, albumInfo);
+            }
+        } else {
+            albumsDiv.appendChild(dojo.doc.createTextNode("No albums found."));
+        }
+        divManager.refreshWindow();
+        
+        // Handles when user clicks an album
+        function onClickAlbum(userId, album) {
+            social.getMediaItemsByAlbum(userId, album.id, function(response) {
+                renderMediaItems(album, response.list);
+                divManager.showMediaItems();
+            });
+        }
+    }
+    
+    /*
+     * Convenience function to retrieve albums and render.
+     */
+    function renderAlbumsByUser(userId, callback) {
+        social.getAlbumsByUser(userId, function(response) {
+            renderAlbums(response.list);
+            divManager.showAlbums();
+            if (callback != null) callback();
+        });
+    }
+    
+    /*
+     * Renders a grid of the given MediaItems.
+     * 
+     * TODO: simplify this by simply taking in 'album', retrieving MediaItems here
+     */
+    function renderMediaItems(album, mediaItems) {
+        console.log('renderMediaItems');
+        dojo.empty('mediaItemsDiv');
+        var mediaItemsDiv = dojo.byId('mediaItemsDiv');
+        var numCols = 5;
+        
+        // Div to display navation bar and Create button
+        var topDiv = dojo.create('div', null, mediaItemsDiv);
+        var table = dojo.create('table', null, topDiv);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        var td = dojo.create('td', {style: 'width:100%'}, tr);
+        dojo.create('a', {innerHTML: 'Albums', href: 'javascript:;', onclick: dojo.hitch(this, renderAlbumsByUser, viewer.id, null)}, td);
+        td.appendChild(dojo.doc.createTextNode(' > ' + album.title));
+        td = dojo.create('td', {style: 'width:100%'}, tr);
+        var createButton = new dijit.form.Button({label: '+ New MediaItem', onClick: dojo.hitch(this, editMediaItemPopup, album, null)});
+        td.appendChild(createButton.domNode);
+        
+        // Div to display MediaItems in a grid
+        var gridDiv = dojo.create('div', null, mediaItemsDiv);
+        if (mediaItems.length > 0) {
+            var table = dojo.create('table', null, gridDiv);
+            var tbody = dojo.create('tbody', null, table);
+            var tr = null;
+            for (i = 0; i < mediaItems.length; i++) {
+                if (i % numCols == 0) {
+                    tr = dojo.create('tr', null, tbody);
+                }
+                var td = dojo.create('td', {className: 'mediaItemBox'}, tr);
+                var imageTd = dojo.create('tr', null, td).appendChild(dojo.create('td', {className: 'mediaItemThumbnail'}));
+                if (mediaItems[i].url) {
+                    var imageLink = dojo.create('a', {href: "javascript:;", onclick: dojo.hitch(this, renderMediaItem, album, mediaItems[i])}, imageTd);
+                    imageLink.appendChild(dojo.create('img', {src: mediaItems[i].thumbnailUrl, onerror: "this.src='" + docUrl + "';", style:'height:100px;'}));
+                } else {
+                    dojo.create('img', {src: mediaItems[i].thumbnailUrl, onerror: "this.src='" + docUrl + "';", style:'height:100px;'}, imageTd);
+                }
+                var titleTd = dojo.create('tr', null, td).appendChild(dojo.create('td', {style: "text-align:center; font-family:'comic sans ms';white-space:nowrap;"}));
+                titleTd.appendChild(dojo.doc.createTextNode(mediaItems[i].title));
+                var actionsTd = dojo.create('tr', null, td).appendChild(dojo.create('td', {className: 'actionLinks', style: 'text-align: center;'}));
+                dojo.create('a', {innerHTML: 'edit', href: 'javascript:;', onclick: dojo.hitch(this, editMediaItemPopup, album, mediaItems[i])}, actionsTd);
+                actionsTd.appendChild(dojo.doc.createTextNode(' | '));
+                dojo.create('a', {innerHTML: 'delete', href: 'javascript:;', onclick: dojo.hitch(this, deleteMediaItemPopup, album, mediaItems[i])}, actionsTd);
+            }
+        } else {
+            gridDiv.appendChild(dojo.doc.createTextNode('Album is empty'));
+        }
+        divManager.refreshWindow();
+    }
+    
+    /*
+     * Convenience function to retriev & render MediaItems by Album.
+     */
+    function retrieveAndRenderMediaItems(album) {
+        social.getMediaItemsByAlbum(viewer.id, album.id, function(response) {
+            divManager.showMediaItems();
+            renderMediaItems(album, response.list);
+        });
+    }
+    
+    /*
+     * Renders the view for a single MediaItem.
+     */
+    function renderMediaItem(album, mediaItem) {
+        console.log('renderMediaItem');
+        dojo.empty('mediaItemDiv');
+        var mediaItemDiv = dojo.byId('mediaItemDiv');
+        
+        // Div to display navation bar and Create button
+        var topDiv = dojo.create('div', null, mediaItemDiv);
+        var table = dojo.create('table', null, topDiv);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        var td = dojo.create('td', {style: 'width:100%'}, tr);
+        dojo.create('a', {innerHTML: 'Albums', href: 'javascript:;', onclick: dojo.hitch(this, renderAlbumsByUser, viewer.id, null)}, td);
+        td.appendChild(dojo.doc.createTextNode(" > "));
+        dojo.create('a', {innerHTML: album.title, href: "javascript:;", onclick: dojo.hitch(this, retrieveAndRenderMediaItems, album)}, td);
+        td.appendChild(dojo.doc.createTextNode(" > " + mediaItem.title));
+        
+        // Div to show MediaItem
+        var itemDiv = dojo.create('div', null, mediaItemDiv);
+        var table = dojo.create('table', null, itemDiv);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        var td = dojo.create('td', null, tr);
+        dojo.create('img', {src: mediaItem.url}, td);
+        if (mediaItem.description) {
+            tr = dojo.create('tr', null, tbody);
+            td = dojo.create('td', null, tr);
+            td.appendChild(dojo.doc.createTextNode(mediaItem.description));
+        }
+        
+        divManager.showMediaItem();
+    }
+    
+    /*
+     * Popup to edit album.
+     */
+    function editAlbumPopup(album) {
+        console.log('editAlbumPopup: ' + JSON.stringify(album));
+        
+        var title = (album == null ? 'Create' : 'Edit') + ' Album';
+        var dialog = new dijit.Dialog({id: 'editAlbumPopup', title: title, onCancel: destroyDialog});
+        dojo.body().appendChild(dialog.domNode);
+        
+        var formDiv = dojo.create('div', {id: 'editAlbumFormDiv'});
+        var form = new dijit.form.Form({id: 'editAlbumForm'});
+        formDiv.appendChild(form.domNode);
+        var table = dojo.create('table', null, form.domNode);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Title', for: 'title'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'title',
+                value: album == null ? '' : album.title
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Thumnail URL', for: 'thumbnail'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'thumbnail',
+                value: album == null ? '' : album.thumbnailUrl
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Description', for: 'description'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.Textarea({
+                name: 'description',
+                value: album == null ? '' : album.description
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        var buttonTd = dojo.create('td', {colspan: '2', align: 'center'}, tr);
+        buttonTd.appendChild(new dijit.form.Button({
+                label: 'Save',
+                onClick: saveForm
+            }).domNode
+        );
+        buttonTd.appendChild(new dijit.form.Button({
+                label: 'Cancel',
+                onClick: destroyDialog
+            }).domNode
+        );
+        
+        dialog.set('content', formDiv);
+        dialog.show();
+        
+        function saveForm() {
+            console.log('saveForm');
+            var values = form.get('value');
+            var newAlbum = {
+                title: values.title,
+                thumbnailUrl: values.thumbnail,
+                description: values.description,
+                ownerId: viewer.id  // TODO: bug? Albums service should set this
+            };
+            if (album == null) {
+                social.createAlbum(viewer.id, newAlbum, function(response) {
+                    console.log('created album response: ' + JSON.stringify(response));
+                    renderAlbumsByUser(viewer.id);
+                });
+            } else {
+                social.updateAlbum(viewer.id, album.id, newAlbum, function(response) {
+                    console.log('updated album response: ' + JSON.stringify(response));
+                    renderAlbumsByUser(viewer.id);
+                });
+            }
+            destroyDialog();
+        }
+        
+        // Handles destroying the dialog popup
+        function destroyDialog() {
+            console.log('destroyDialog');
+            dialog.destroyRecursive(false);
+            dialog.destroyRendering(false);
+            dialog.destroy(false);
+        }
+    }
+    
+    /*
+     * Popup to edit MediaItem.
+     */
+    function editMediaItemPopup(album, mediaItem) {
+        console.log('editMediaItemPopup: ' + JSON.stringify(mediaItem));
+        
+        var albumId = mediaItem == null ? album.id : mediaItem.albumId;
+        var title = (mediaItem == null ? 'Create' : 'Edit') + ' MediaItem';
+        var dialog = new dijit.Dialog({id: 'editMediaItemPopup', title: title, onCancel: destroyDialog});
+        dojo.body().appendChild(dialog.domNode);
+        
+        // Form div
+        var formDiv = dojo.create('div', {id: 'editMediaItemFormDiv'});
+        var form = new dijit.form.Form({id: 'editMediaItemForm'});
+        formDiv.appendChild(form.domNode);
+        var table = dojo.create('table', null, form.domNode);
+        var tbody = dojo.create('tbody', null, table);
+        var tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Title', for: 'title'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'title',
+                value: mediaItem == null ? '' : mediaItem.title
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Description', for: 'description'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.Textarea({
+                name: 'description',
+                value: mediaItem == null ? '' : mediaItem.description
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Type', for: 'type'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'type',
+                value: mediaItem == null ? '' : mediaItem.type
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'Thumnail URL', for: 'thumbnailUrl'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'thumbnailUrl',
+                value: mediaItem == null ? '' : mediaItem.thumbnailUrl
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        dojo.create('td', null, tr).appendChild(dojo.create('label', {innerHTML: 'URL', for: 'url'}));
+        dojo.create('td', null, tr).appendChild(
+            new dijit.form.ValidationTextBox({
+                name: 'url',
+                value: mediaItem == null ? '' : mediaItem.url
+            }).domNode
+        );
+        tr = dojo.create('tr', null, tbody);
+        var buttonTd = dojo.create('td', {colspan: '2', align: 'center'}, tr);
+        buttonTd.appendChild(new dijit.form.Button({
+                label: 'Save',
+                onClick: saveForm
+            }).domNode
+        );
+        buttonTd.appendChild(new dijit.form.Button({
+                label: 'Cancel',
+                onClick: destroyDialog
+            }).domNode
+        );
+        
+        // Textarea div for JSON
+        var textAreaDiv = dojo.create('div', {style: "width:100%; height:100%;", id: 'textAreaDiv'});
+        var textArea = new dijit.form.Textarea({value: JSON.stringify(mediaItem), rows: "20"});
+        textAreaDiv.appendChild(textArea.domNode);
+        
+        // Put divs together
+        var tabContainer = new dijit.layout.TabContainer({style: "width:400px; height:300px;"});
+        var formContentPane = new dijit.layout.ContentPane({title: "Form", content: formDiv});
+        tabContainer.addChild(formContentPane);
+        var textAreaContentPane = new dijit.layout.ContentPane({title: "JSON", content: textAreaDiv});
+        tabContainer.addChild(textAreaContentPane);
+        tabContainer.startup();
+        var dialogDiv = dojo.create('div', null);
+        dialogDiv.appendChild(tabContainer.domNode);
+        
+        dialog.set('content', dialogDiv);
+        dialog.show();
+        
+        function saveForm() {
+            console.log('saveForm mediaItem');
+            var values = form.get('value');
+            var newMediaItem = {
+                title: values.title,
+                description: values.description,
+                type: values.type,
+                thumbnailUrl: values.thumbnailUrl,
+                url: values.url
+            };
+            if (newMediaItem.type == null || newMediaItem.type == "") newMediaItem.type = "image";
+            if (mediaItem == null) {
+                social.createMediaItem(viewer.id, albumId, newMediaItem, function(response) {
+                    console.log('created MediaItem response: ' + JSON.stringify(response));
+                    social.getMediaItemsByAlbum(viewer.id, album.id, function(response) {
+                        renderMediaItems(album, response.list);
+                    });
+                });
+            } else {
+                social.updateMediaItem(viewer.id, albumId, mediaItem.id, newMediaItem, function(response) {
+                    console.log('updated MediaItem response: ' + JSON.stringify(response));
+                    social.getMediaItemsByAlbum(viewer.id, album.id, function(response) {
+                        renderMediaItems(album, response.list);
+                    });
+                });
+            }
+            destroyDialog();
+        }
+        
+        // Handles destroying the dialog popup
+        function destroyDialog() {
+            console.log('destroyDialog');
+            dialog.destroyRecursive(false);
+            dialog.destroyRendering(false);
+            dialog.destroy(false);
+        }
+    }
+    
+    /*
+     * Popup to confirm that the user wants to delete album.
+     */
+    function deleteAlbumPopup(album) {
+        console.log('deleteAlbumPopup');
+        if (confirm("Delete '" + album.title + "'?")) {
+            social.deleteAlbum(viewer.id, album.id, function(response) {
+                console.log('delete album response: ' + JSON.stringify(response));
+                renderAlbumsByUser(viewer.id);
+            });
+        }
+    }
+    
+    /*
+     * Popup to confirm user wants to delete MediaItem.
+     */
+    function deleteMediaItemPopup(album, mediaItem) {
+        console.log('deleteMediaItemPopup');
+        var albumId = mediaItem.albumId;
+        if (confirm("Delete '" + mediaItem.title + "'?")) {
+            social.deleteMediaItem(viewer.id, albumId, mediaItem.id, function(response) {
+                console.log('delete mediaItem response: ' + JSON.stringify(response));
+                social.getMediaItemsByAlbum(viewer.id, albumId, function(response) {
+                    renderMediaItems(album, response.list);
+                });
+            });
+        }
+    }
+}
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Social.js
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Social.js?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Social.js (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/Social.js Fri Oct 29 15:34:40 2010
@@ -0,0 +1,156 @@
+/**
+ * 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.
+ */
+
+/*
+ * Defines high level functionality to interact with the OpenSocial API.
+ */
+function SocialWrapper() {
+
+    /*
+     * Retrieves the current viewer.
+     */
+    this.getViewer = function(callback) {
+        osapi.people.getViewer().execute(callback);
+    }
+    
+    /*
+     * Retrieves the current owner.
+     */
+    this.getOwner = function(callback) {
+        osapi.people.getOwner().execute(callback);
+    }
+    
+    //------------------------ ALBUMS ----------------------
+    /*
+     * Retrieves albums by ID(s).
+     */
+    this.getAlbumsById = function(userId, albumId, callback) {
+        var params = {userId: userId, albumId: albumId};
+        osapi.albums.get(params).execute(callback);
+    }
+     
+    /*
+     * Retrieves albums by user.
+     */
+    this.getAlbumsByUser = function(userId, callback) {
+        osapi.albums.get({userId: userId}).execute(callback);
+    }
+    
+    /*
+     * Retrieves albums by group.
+     */
+    this.getAlbumsByGroup = function(userId, groupId, callback) {
+        osapi.albums.get({userId: userId, groupId: groupId}).execute(callback);
+    }
+    
+    /*
+     * Creates an album for the given user.
+     */
+    this.createAlbum = function(userId, album, callback) {
+        var params = {
+            userId: userId,
+            album: album
+        };
+        osapi.albums.create(params).execute(callback);
+    }
+    
+    /*
+     * Updates an album by ID.
+     */
+    this.updateAlbum = function(userId, albumId, album, callback) {
+        var params = {
+            userId: userId,
+            albumId: albumId,
+            album: album
+        };
+        osapi.albums.update(params).execute(callback);
+    }
+    
+    /*
+     * Deletes an album by ID.
+     */
+    this.deleteAlbum = function(userId, albumId, callback) {
+        var params = {userId: userId, albumId: albumId};
+        osapi.albums.delete(params).execute(callback);
+    }
+    
+    //------------------------------- MEDIAITEMS ----------------------------
+    /*
+     * Creates a MediaItem.
+     */
+    this.createMediaItem = function(userId, albumId, mediaItem, callback) {
+        var params = {
+            userId: userId,
+            albumId: albumId,
+            mediaItem: mediaItem
+        };
+        osapi.mediaItems.create(params).execute(callback);
+    }
+    
+    /*
+     * Updates a MediaItem by ID.
+     */
+    this.updateMediaItem = function(userId, albumId, mediaItemId, mediaItem, callback) {
+        var params = {
+            userId: userId,
+            albumId: albumId,
+            mediaItemId: mediaItemId,
+            mediaItem: mediaItem
+        };
+        console.log("PARAMS: " + JSON.stringify(params));
+        osapi.mediaItems.update(params).execute(callback);
+    }
+    
+    /*
+     * Retrieves MediaItems by ID(s).
+     */
+    this.getMediaItemsById = function(userId, albumId, mediaItemId, callback) {
+        var params = {
+            userId: userId,
+            albumId: albumId,
+            mediaItemId: mediaItemId
+        };
+        osapi.mediaItems.get(params).execute(callback);
+    }
+    
+    /*
+     * Retrieves MediaItems by album.
+     */
+    this.getMediaItemsByAlbum = function(userId, albumId, callback) {
+        osapi.mediaItems.get({userId: userId, albumId: albumId}).execute(callback);
+    }
+     
+    /*
+     * Retrieves MediaItems by user and group.
+     */
+    this.getMediaItemsByUser = function(userId, groupId, callback) {
+        osapi.mediaItems.get({userId: userId, groupId: groupId}).execute(callback);
+    }
+     
+    /*
+     * Deletes a MediaItem by ID.
+     */
+    this.deleteMediaItem = function(userId, albumId, mediaItemId, callback) {
+        var params = {
+            userId: userId,
+            albumId: albumId,
+            mediaItemId: mediaItemId
+        };
+        osapi.mediaItems.delete(params).execute(callback);
+    }
+}
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/styles.css
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/styles.css?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/styles.css (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/examples/media/styles.css Fri Oct 29 15:34:40 2010
@@ -0,0 +1,110 @@
+/**
+ * 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.
+ */
+
+/* ============ ROUND 2 ============== */
+
+td.albumsTitle {
+    font-family:'comic sans ms';
+    width: 100%;
+    font-size:24px;
+}
+
+td.albumListThumbnail {
+    width: 10%;
+    height: 75px;
+}
+
+td.albumListRight {
+    width: 90%;
+}
+
+td.actionLinks {
+    width:100%;
+    font-size:12px;
+}
+
+td.albumListTitle {
+    font-size:24px;
+    white-space:nowrap;
+    font-family:'comic sans ms';
+}
+
+td.albumListDescription {
+    font-family:'comic sans ms';
+}
+
+.albumsTable {
+    width:100%;
+    border-style:solid;
+    background-color:#b0c4de;
+}
+
+td.mediaItemThumbnail {
+    height:100%;
+}
+
+td.mediaItemBox {
+    width: 150px;
+    height: 100px;
+}
+
+.mediaItemControls {
+
+}
+
+
+/* ============ ROUND 1 ============== */
+.temp1 {background-color:#6495ed;}
+.temp2 {background-color:#e0ffff;}
+.temp3 {
+    background-color:#b0c4de;
+    background-image:url('img_flwr.png');
+    background-repeat:no-repeat;
+    background-position:top right;
+}
+
+td2 {
+    border-style:solid;
+}
+
+td.albumLeft {
+    width:10%;
+}
+
+td.albumRight {
+    width: 90%;
+}
+
+
+
+td.albumEdit {
+    width:100%;
+    text-align:right;
+    vertical-align:middle;
+    font-size:12px;
+}
+
+
+
+.albumTitleStyle {
+    color: blue;
+    
+}
+.albumElement {
+    background-color:#b0c4de;
+}

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.html
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.html?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.html (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.html Fri Oct 29 15:34:40 2010
@@ -0,0 +1,94 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Gadget testing container</title>
+<link rel="stylesheet" href="../container/gadgets.css">
+<style type="text/css">
+  body {
+    font-family: arial, sans-serif;
+  }
+
+  #headerDiv {
+    padding: 10px;
+    margin-bottom: 20px;
+    background-color: #e5ecf9;
+    color: #3366cc;
+    font-size: larger;
+    font-weight: bold;
+  }
+
+  .subTitle {
+    font-size: smaller;
+    float: right;
+  }
+
+  .gadgets-gadget-chrome {
+    width: 60%;
+    float: none;
+    margin: auto;
+  }
+
+  .gadgets-gadget {
+    width: 100%;
+  }
+
+</style>
+
+<script type="text/javascript" src="/gadgets/js/core:rpc:pubsub:shindig-container.js?c=1&debug=1"></script>
+<script type="text/javascript" src="samplecontainer.js"></script>
+
+</head>
+<body onLoad="shindig.samplecontainer.initSampleContainer();
+    shindig.samplecontainer.unpackFormState(); shindig.samplecontainer.initGadget();">
+  <div id="headerDiv">
+    <div style="float:left">Gadget testing container</div>
+    <div class="subTitle">
+      Displaying gadget: <input type="text" size="75" id="gadgetUrl"/>
+      <input type="checkbox" id="useCacheCheckbox" checked="true"
+       /><label for="useCacheCheckbox">use cache</label>
+      <input type="checkbox" id="useCajaCheckbox"
+       /><label for="useCajaCheckbox">use caja</label>
+      <input type="checkbox" id="useDebugCheckbox"
+       /><label for="useDebugCheckbox">use debug</label>
+
+      <br/>
+
+      Using state: <input type="text" size="75" id="stateFileUrl"/>
+      <input type="checkbox" id="doEvilCheckbox"
+       /><label for="doEvilCheckbox">do evil</label>
+
+      <br/>
+      <br/>
+      Viewer id: <input type="text" size="20" id="viewerId"/>
+      Owner id: <input type="text" size="20" id="ownerId"/>
+
+      <br/>
+
+      <input type="button" value="reset all" onclick="shindig.samplecontainer.changeGadgetUrl();"/>
+      <input type="button" value="dump state" onclick="shindig.samplecontainer.dumpStateFile();"/>
+      <input type="button" value="Send Hello" onclick="shindig.samplecontainer.sendHello();"/>
+    </div>
+    <div style="clear:both; height: 1px;">&nbsp;</div>
+  </div>
+
+  <div id="gadgetState" style="font-size:smaller"></div>
+  <div id="gadget-chrome" class="gadgets-gadget-chrome"></div>
+</body>
+</html>

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.js
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.js?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.js (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/samplecontainer.js Fri Oct 29 15:34:40 2010
@@ -0,0 +1,302 @@
+/**
+ * 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.
+ */
+/**
+ * @Functions for the samplecontainer
+ */
+
+/**
+ * Public Shindig namespace with samplecontainer object
+ */
+
+var shindig = shindig || {};
+shindig.samplecontainer = {};
+
+/**
+ * Hide our functions and variables from other javascript
+ */
+
+(function(){
+
+  /**
+   * Private Variables
+  */
+
+  var parentUrl = document.location.href;
+  var baseUrl = parentUrl.substring(0, parentUrl.indexOf('samplecontainer.html'));
+
+  // TODO: This is gross, it needs to use the config just like the gadget js does
+  var socialDataPath = document.location.protocol + "//" + document.location.host
+    + "/social/rest/samplecontainer/";
+
+  var gadgetUrlMatches = /[?&]url=((?:[^#&]+|&amp;)+)/.exec(parentUrl);
+  var gadgetUrl = (gadgetUrlMatches)
+      ? gadgetUrlMatches[1]
+      : baseUrl + 'examples/SocialHelloWorld.xml';
+
+  var gadgetUrlCookie = 'sampleContainerGadgetUrl';
+
+  var stateFileUrl = baseUrl + '../sampledata/canonicaldb.json';
+  var stateFileUrlCookie = 'sampleContainerStateFileUrl';
+
+  var useCaja;
+  var useCache;
+  var useDebug;
+  var doEvil;
+  var gadget;
+
+  var viewerId = "john.doe";
+  var ownerId = "canonical";
+
+  var viewMatches = /[?&]view=((?:[^#&]+|&amp;)+)/.exec(parentUrl);
+  var current_view = (viewMatches)
+      ? viewMatches[1]
+      : "default";
+
+  /**
+   * Public Variables
+   */
+
+  /**
+   * Private Functions
+   */
+
+  function generateSecureToken() {
+    // TODO: Use a less silly mechanism of mapping a gadget URL to an appid
+    var appId = 0;
+    for (var i = 0; i < gadgetUrl.length; i++) {
+      appId += gadgetUrl.charCodeAt(i);
+    }
+    var fields = [ownerId, viewerId, appId, "shindig", gadgetUrl, "0", "default"];
+    for (var i = 0; i < fields.length; i++) {
+      // escape each field individually, for metachars in URL
+      fields[i] = escape(fields[i]);
+    }
+    return fields.join(":");
+  }
+
+  SampleContainerGadget = function(opt_params) {
+    shindig.BaseIfrGadget.call(this, opt_params);
+
+    // mix-in IfrGadget functions
+    for (var name in shindig.IfrGadget) if (shindig.IfrGadget.hasOwnProperty(name)) {
+      SampleContainerGadget[name] = shindig.IfrGadget[name];
+    }
+  };
+
+  SampleContainerGadget.inherits(shindig.BaseIfrGadget);
+
+  SampleContainerGadget.prototype.getAdditionalParams = function() {
+    var params = '';
+
+    if (useCaja) {
+      params += "&caja=1&libs=caja";
+    }
+    if (useDebug) {
+      params += "&debug=1";
+    }
+    return params;
+  };
+
+  shindig.container.gadgetClass = SampleContainerGadget;
+
+  function setEvilBit() {
+    sendRequestToServer('setevilness/' + doEvil, 'POST');
+  };
+
+  function reloadStateFile(opt_callback) {
+    sendRequestToServer('setstate', 'POST',
+        gadgets.json.stringify({"fileurl" : stateFileUrl}),
+        opt_callback);
+  };
+
+  function sendRequestToServer(url, method, opt_postParams, opt_callback, opt_excludeSecurityToken) {
+    // TODO: Should re-use the jsoncontainer code somehow
+    opt_postParams = opt_postParams || {};
+
+    var makeRequestParams = {
+      "CONTENT_TYPE" : "JSON",
+      "METHOD" : method,
+      "POST_DATA" : opt_postParams};
+
+    if (!opt_excludeSecurityToken) {
+      url = socialDataPath + url + "?st=" + gadget.secureToken;
+    }
+
+    gadgets.io.makeNonProxiedRequest(url,
+      function(data) {
+        data = data.data;
+        if (opt_callback) {
+            opt_callback(data);
+        }
+      },
+      makeRequestParams,
+      "application/javascript"
+    );
+  };
+
+  function generateGadgets(metadata) {
+    // TODO: The gadget.js file should really have a clearGadgets method
+    shindig.container.view_ = current_view;
+    shindig.container.gadgets_ = {};
+    for (var i = 0; i < metadata.gadgets.length; i++) {
+      gadget = shindig.container.createGadget({'specUrl': metadata.gadgets[i].url,
+          'title': metadata.gadgets[i].title, 'userPrefs': metadata.gadgets[i].userPrefs});
+      // Shindigs rpc code uses direct javascript calls when running on the same domain
+      // to simulate cross-domain when running sample container we replace 
+      // 'localhost' with '127.0.0.1' 
+      var iframeBaseUrl = baseUrl.replace("localhost", "127.0.0.1") + '../../gadgets/';
+
+      gadget.setServerBase(iframeBaseUrl);
+      gadget.secureToken = escape(generateSecureToken());
+      shindig.container.addGadget(gadget);
+    }
+
+    shindig.container.layoutManager.setGadgetChromeIds(['gadget-chrome']);
+    reloadStateFile(function() {
+      shindig.container.renderGadgets();
+    });
+  };
+
+  function refreshGadgets(metadata) {
+    // TODO: The gadget.js file should really have a getGadgets method
+    for (var gadget in shindig.container.gadgets_) {
+      var gadgetMetadata = metadata.gadgets[0];
+      shindig.container.gadgets_[gadget].title = gadgetMetadata.title;
+      shindig.container.gadgets_[gadget].specUrl = gadgetMetadata.url;
+      shindig.container.gadgets_[gadget].userPrefs = gadgetMetadata.userPrefs;
+      shindig.container.gadgets_[gadget].secureToken = escape(generateSecureToken());
+    }
+    reloadStateFile(function() {
+      shindig.container.refreshGadgets();
+    });
+  }
+
+  function requestGadgetMetaData(opt_callback) {
+    var request = {
+      context: {
+        country: "default",
+        language: "default",
+        view: current_view,
+        container: "default"
+      },
+      gadgets: [{
+        url: gadgetUrl,
+        moduleId: 1
+      }]
+    };
+
+    sendRequestToServer("/gadgets/metadata", "POST",
+        gadgets.json.stringify(request), opt_callback, true);
+  }
+
+  /**
+   * Public Functions
+   */
+  shindig.samplecontainer.initSampleContainer = function() {
+     // Upon initial load, check for the cache query parameter (we don't want
+     // to overwrite when clicking "refresh all")
+     var cacheUrlMatches = /[?&]cache=([01])/.exec(parentUrl);
+     if (cacheUrlMatches && cacheUrlMatches[1] == "0") {
+       document.getElementById("useCacheCheckbox").checked = false;
+     }
+     gadgets.pubsubrouter.init(function() { return gadgetUrl; });
+  };
+
+  shindig.samplecontainer.initGadget = function() {
+    // Fetch cookies
+    var cookieGadgetUrl = decodeURIComponent(shindig.cookies.get(gadgetUrlCookie));
+    if (cookieGadgetUrl && cookieGadgetUrl != "undefined") {
+      gadgetUrl = cookieGadgetUrl;
+    }
+
+    var cookieStateFileUrl = decodeURIComponent(shindig.cookies.get(stateFileUrlCookie));
+    if (cookieStateFileUrl && cookieStateFileUrl != "undefined") {
+      stateFileUrl = cookieStateFileUrl;
+    }
+
+    // Setup state file
+    document.getElementById("stateFileUrl").value = stateFileUrl;
+
+    // Render gadget
+    document.getElementById("gadgetUrl").value = gadgetUrl;
+
+    // Viewer and Owner
+    document.getElementById("viewerId").value = viewerId;
+    document.getElementById("ownerId").value = ownerId;
+
+    requestGadgetMetaData(generateGadgets);
+  };
+
+  shindig.samplecontainer.unpackFormState = function() {
+    useCaja = document.getElementById("useCajaCheckbox").checked;
+    useCache = document.getElementById("useCacheCheckbox").checked;
+    useDebug = document.getElementById("useDebugCheckbox").checked;
+    doEvil = document.getElementById("doEvilCheckbox").checked;
+  };
+
+  shindig.samplecontainer.changeGadgetUrl = function() {
+    shindig.samplecontainer.unpackFormState();
+    shindig.container.nocache_ = useCache ? 0 : 1;
+
+    setEvilBit();
+
+    stateFileUrl = document.getElementById("stateFileUrl").value;
+    shindig.cookies.set(stateFileUrlCookie, encodeURIComponent(stateFileUrl));
+
+    viewerId = document.getElementById("viewerId").value;
+    ownerId = document.getElementById("ownerId").value;
+    gadgetUrl = document.getElementById("gadgetUrl").value;
+
+    shindig.cookies.set(gadgetUrlCookie, encodeURIComponent(gadgetUrl));
+
+    requestGadgetMetaData(refreshGadgets);
+  };
+
+  shindig.samplecontainer.dumpStateFile = function() {
+    sendRequestToServer('dumpstate', 'GET', null,
+      function(data) {
+        if (!data) {
+          alert("Could not dump the current state.");
+        }
+        document.getElementById('gadgetState').innerHTML
+          = gadgets.json.stringify(data);
+      }
+    );
+  };
+
+  shindig.samplecontainer.sendHello = function() {
+    gadgets.pubsubrouter.publish('helloworld', 'hello from the container');
+  };
+
+  osapi.messages = {};
+  osapi.messages.requestSend = function(request, callback) {
+    alert("osapi.messages.requestSend called");
+    callback({});
+  };
+
+  osapi.requestShareApp = function(request, callback) {
+    alert("osapi.requestShareApp called");
+    callback({});
+  };
+
+  osapi.requestPermission = function(request, callback) {
+    alert("osapi.requestPermission called");
+    callback({});
+  };
+
+})();

Added: shindig/sandbox/trunk/cmis-binding/content/samplecontainer/state.dtd
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/content/samplecontainer/state.dtd?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/content/samplecontainer/state.dtd (added)
+++ shindig/sandbox/trunk/cmis-binding/content/samplecontainer/state.dtd Fri Oct 29 15:34:40 2010
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+<!ELEMENT container (people, appId?,
+    personAppData?, activities?)>
+
+<!ELEMENT people (person*)>
+
+<!ELEMENT person (friend*, count*, address*)>
+<!ATTLIST person id CDATA #REQUIRED
+    name CDATA #IMPLIED
+    gender CDATA #IMPLIED
+    phone CDATA #IMPLIED
+    thumbnailUrl CDATA #IMPLIED
+    profileUrl CDATA #IMPLIED>
+
+<!ELEMENT friend (#PCDATA)>
+
+<!ELEMENT count (#PCDATA)>
+<!ATTLIST count type CDATA #REQUIRED>
+
+<!ELEMENT address (latitude?, longitude?, streetAddress?, locality?, region?,
+    postalCode?, country?, extendedAddress?, poBox?, unstructuredAddress?)>
+<!ATTLIST address type CDATA #REQUIRED>
+
+<!ELEMENT latitude (#PCDATA)>
+<!ELEMENT longitude (#PCDATA)>
+<!ELEMENT streetAddress (#PCDATA)>
+<!ELEMENT locality (#PCDATA)>
+<!ELEMENT region (#PCDATA)>
+<!ELEMENT postalCode (#PCDATA)>
+<!ELEMENT country (#PCDATA)>
+<!ELEMENT extendedAddress (#PCDATA)>
+<!ELEMENT poBox (#PCDATA)>
+<!ELEMENT unstructuredAddress (#PCDATA)>
+
+<!ELEMENT appId (#PCDATA)>
+
+<!ELEMENT personAppData (data*)>
+
+<!ELEMENT data (#PCDATA)>
+<!ATTLIST data field CDATA #REQUIRED person CDATA #IMPLIED>
+
+<!ELEMENT activities (stream*)>
+
+<!ELEMENT stream (activity*)>
+<!ATTLIST stream title CDATA #REQUIRED
+    url CDATA #IMPLIED
+    userId CDATA #IMPLIED
+    sourceUrl CDATA #IMPLIED
+    faviconUrl CDATA #IMPLIED>
+
+<!ELEMENT activity (mediaItem*)>
+<!ATTLIST activity title CDATA #REQUIRED
+    id CDATA #REQUIRED
+    externalId CDATA #IMPLIED
+    body CDATA #IMPLIED
+    url CDATA #IMPLIED
+    postedTime CDATA #IMPLIED>
+
+<!ELEMENT mediaItem (#PCDATA)>
+<!ATTLIST mediaItem mimeType CDATA #REQUIRED
+    url CDATA #REQUIRED
+    type CDATA #IMPLIED>
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/pom.xml
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/pom.xml?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/pom.xml (added)
+++ shindig/sandbox/trunk/cmis-binding/pom.xml Fri Oct 29 15:34:40 2010
@@ -0,0 +1,209 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<!-- Project Info -->
+	<groupId>org.apache.shindig</groupId>
+	<artifactId>cmis-binding</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>war</packaging>
+	<name>cmis-binding</name>
+	<description>Binding for CMIS to Albums &amp; MediaItems.</description>
+
+	<!-- Repositories -->
+	<repositories>
+		<repository>
+			<id>central</id>
+			<name>Maven Repository Switchboard</name>
+			<layout>default</layout>
+			<url>http://repo1.maven.org/maven2</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+		<repository>
+			<id>java.net</id>
+			<url>http://download.java.net/maven/1/</url>
+		</repository>
+	</repositories>
+	
+	<!-- Build -->
+	<build>
+		<finalName>${project.artifactId}-${pom.version}</finalName>
+		<defaultGoal>install</defaultGoal>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.5</source>
+					<target>1.5</target>
+					<showDeprecation>true</showDeprecation>
+					<compilerArgument>-Xlint:unchecked,deprecation,fallthrough,finally</compilerArgument>
+					<fork>true</fork>
+					<encoding>${project.build.sourceEncoding}</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<phase>package</phase>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<excludeResources>false</excludeResources>
+					<attach>true</attach>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-eclipse-plugin</artifactId>
+				<version>2.3</version>
+				<configuration>
+					<wtpversion>1.5</wtpversion>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-war-plugin</artifactId>
+				<configuration>
+					<webResources>
+						<resource>
+							<!-- this is relative to the pom.xml directory -->
+							<directory>${basedir}/content/</directory>
+							<includes>
+								<include>**/*.*</include>
+							</includes>
+						</resource>
+						<resource>
+							<targetPath>META-INF</targetPath>
+							<directory>target/cmis-binding-${pom.version}/META-INF</directory>
+							<includes>
+								<include>**/*</include>
+							</includes>
+						</resource>
+
+					</webResources>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.4.2</version>
+			</plugin>
+			<plugin>
+				<artifactId>maven-resources-plugin</artifactId>
+				<version>2.3</version>
+			</plugin>
+			<plugin>
+				<groupId>org.mortbay.jetty</groupId>
+				<artifactId>maven-jetty-plugin</artifactId>
+				<configuration>
+					<webAppSourceDirectory>${basedir}/target/cmis-binding-${pom.version}</webAppSourceDirectory>
+					<contextPath>/</contextPath>
+					<webXml>${basedir}/target/cmis-binding-${pom.version}/WEB-INF/web.${runType}.xml</webXml>
+				</configuration>
+			</plugin>
+		</plugins>
+		<resources>
+			<resource>
+				<targetPath>containers/default</targetPath>
+				<directory>${basedir}/config</directory>
+				<includes>
+					<include>container.js</include>
+				</includes>
+			</resource>
+			<resource>
+				<targetPath>config</targetPath>
+				<directory>${basedir}/config</directory>
+				<includes>
+					<include>oauth.json</include>
+				</includes>
+			</resource>
+			<resource>
+				<directory>conf</directory>
+			</resource>
+		</resources>
+	</build>
+	
+	<!-- Dependencies -->
+	<dependencies>
+		<!-- external dependencies -->
+		<dependency>
+			<groupId>org.apache.chemistry.opencmis</groupId>
+			<artifactId>chemistry-opencmis-client-impl</artifactId>
+			<version>0.1.0-incubating</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<version>2.5</version>
+			<scope>compile</scope>
+		</dependency>
+
+		<!-- shindig dependencies -->
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-extras</artifactId>
+			<version>${shindig.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-social-api</artifactId>
+			<version>${shindig.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-gadgets</artifactId>
+			<version>${shindig.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-features</artifactId>
+			<version>${shindig.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-common</artifactId>
+			<version>${shindig.version}</version>
+		</dependency>
+		
+		<!-- shindig test dependencies -->
+		<dependency>
+			<groupId>org.apache.shindig</groupId>
+			<artifactId>shindig-common</artifactId>
+			<version>${shindig.version}</version>
+			<classifier>tests</classifier>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-jdk14</artifactId>
+			<version>1.5.6</version>
+		</dependency>
+	</dependencies>
+	
+	<!-- Properties -->
+	<properties>
+		<pom.version>3.0.0-SNAPSHOT</pom.version>
+		<shindig.version>3.0.0-SNAPSHOT</shindig.version>
+		<junit.version>4.4</junit.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+</project>
\ No newline at end of file

Added: shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/CMISGuiceModule.java
URL: http://svn.apache.org/viewvc/shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/CMISGuiceModule.java?rev=1028804&view=auto
==============================================================================
--- shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/CMISGuiceModule.java (added)
+++ shindig/sandbox/trunk/cmis-binding/src/main/java/org/apache/shindig/extras/cmis/CMISGuiceModule.java Fri Oct 29 15:34:40 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.shindig.extras.cmis;
+
+import org.apache.shindig.extras.cmis.sample.CMISService;
+import org.apache.shindig.social.opensocial.oauth.OAuthDataStore;
+import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.AlbumService;
+import org.apache.shindig.social.opensocial.spi.AppDataService;
+import org.apache.shindig.social.opensocial.spi.MediaItemService;
+import org.apache.shindig.social.opensocial.spi.MessageService;
+import org.apache.shindig.social.opensocial.spi.PersonService;
+import org.apache.shindig.social.sample.SampleModule;
+import org.apache.shindig.social.sample.oauth.SampleOAuthDataStore;
+import org.apache.shindig.social.sample.spi.JsonDbOpensocialService;
+
+import com.google.inject.name.Names;
+
+/**
+ * Configures the Extra modules in shindig-extras.
+ */
+public class CMISGuiceModule extends SampleModule {
+	  @Override
+	  protected void configure() {
+	    bind(String.class).annotatedWith(Names.named("shindig.canonical.json.db"))
+	        .toInstance("sampledata/canonicaldb.json");
+	    bind(ActivityService.class).to(JsonDbOpensocialService.class);
+	    bind(AlbumService.class).to(CMISService.class);
+	    bind(MediaItemService.class).to(CMISService.class);
+	    bind(AppDataService.class).to(JsonDbOpensocialService.class);
+	    bind(PersonService.class).to(JsonDbOpensocialService.class);
+	    bind(MessageService.class).to(JsonDbOpensocialService.class);
+	    bind(OAuthDataStore.class).to(SampleOAuthDataStore.class);
+	  }
+}
\ No newline at end of file