Author: scottbw
Date: Tue Sep 27 19:58:11 2011
New Revision: 1176579

URL: http://svn.apache.org/viewvc?rev=1176579&view=rev
Log:
Added a check in the WidgetInstancesController for widget instances created by 
0.9.0, and migrate them to 0.9.1 using a new MigrationHelper class.  This means 
that users upgrading from 0.9.0 to 0.9.1 should see no loss of data. See 
WOOKIE-243.

Added:
    incubator/wookie/trunk/src/org/apache/wookie/helpers/MigrationHelper.java
Modified:
    
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetInstancesController.java

Modified: 
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetInstancesController.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetInstancesController.java?rev=1176579&r1=1176578&r2=1176579&view=diff
==============================================================================
--- 
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetInstancesController.java
 (original)
+++ 
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetInstancesController.java
 Tue Sep 27 19:58:11 2011
@@ -38,6 +38,7 @@ import org.apache.wookie.beans.util.Pers
 import org.apache.wookie.exceptions.InvalidParametersException;
 import org.apache.wookie.exceptions.ResourceNotFoundException;
 import org.apache.wookie.exceptions.UnauthorizedAccessException;
+import org.apache.wookie.helpers.MigrationHelper;
 import org.apache.wookie.helpers.Notifier;
 import org.apache.wookie.helpers.SharedDataHelper;
 import org.apache.wookie.helpers.WidgetInstanceFactory;
@@ -410,28 +411,65 @@ public class WidgetInstancesController e
                  return instance;
                }
 
-    // If all else fails, try using instance parameters
+               //
+               // If all else fails, try using instance parameters
+               //
                try {
-                       String apiKey = 
URLDecoder.decode(request.getParameter("api_key"), "UTF-8"); //$NON-NLS-1$
-                       String userId = 
URLDecoder.decode(request.getParameter("userid"), "UTF-8"); //$NON-NLS-1$
-                       String sharedDataKey = 
request.getParameter("shareddatakey");    //$NON-NLS-1$;
-                       String widgetId = request.getParameter("widgetid");
-               sharedDataKey = 
SharedDataHelper.getInternalSharedDataKey(apiKey, widgetId, sharedDataKey);
-                       if (widgetId != null){
-                               widgetId = URLDecoder.decode(widgetId, 
"UTF-8"); //$NON-NLS-1$
-                               _logger.debug("Looking for widget instance with 
widgetid of " + widgetId);
-                               instance = 
persistenceManager.findWidgetInstanceByGuid(apiKey, userId, sharedDataKey, 
widgetId);
-                       } else {
-                               String serviceType = 
URLDecoder.decode(request.getParameter("servicetype"), "UTF-8"); //$NON-NLS-1$
-                               _logger.debug("Looking for widget instance of 
service type " + serviceType);
-                               instance = 
persistenceManager.findWidgetInstance(apiKey, userId, sharedDataKey, 
serviceType);
-                       }
-                       if (instance == null) {
-                               _logger.debug("No widget instance found for 
APIkey= "+apiKey+" userId="+userId+" widgetId="+widgetId);
-                       }
-                       return instance;
+
+                 String apiKey = 
URLDecoder.decode(request.getParameter("api_key"), "UTF-8"); //$NON-NLS-1$
+                 String userId = 
URLDecoder.decode(request.getParameter("userid"), "UTF-8"); //$NON-NLS-1$
+                 String sharedDataKey = request.getParameter("shareddatakey"); 
 //$NON-NLS-1$;
+                 String widgetId = request.getParameter("widgetid");
+                 String serviceType = request.getParameter("servicetype");
+
+                 //
+                 // First see if there is a legacy 0.9.0 instance that matches
+                 //
+                 // NOTE: This step will be deprecated in future releases
+                 //
+                 instance = MigrationHelper.findLegacyWidgetInstance(apiKey, 
userId, sharedDataKey, widgetId, serviceType);
+
+                 // 
+                 // Otherwise, look for a 0.9.1 or later version
+                 //
+                 if (instance == null){   
+                   String internalSharedDataKey = 
SharedDataHelper.getInternalSharedDataKey(apiKey, widgetId, sharedDataKey);
+                   instance = findWidgetInstance(apiKey, userId, 
internalSharedDataKey, widgetId, serviceType);
+                 }
+
+                 if (instance == null) {
+                   _logger.debug("No widget instance found for APIkey= 
"+apiKey+" userId="+userId+" widgetId="+widgetId);
+                 }
+
+                 return instance;
+
                } catch (UnsupportedEncodingException e) {
-                       throw new RuntimeException("Server must support UTF-8 
encoding", e);
+                 throw new RuntimeException("Server must support UTF-8 
encoding", e);
                } //$NON-NLS-1$
        }
+
+       /**
+        * Find a widget instance using instance parameters, either by widget 
URI (guid) or service type
+        * 
+        * @param apiKey
+        * @param userId
+        * @param sharedDataKey
+        * @param widgetId
+        * @param serviceType
+        * @return the widget instance, or null if there is no matching instance
+        * @throws UnsupportedEncodingException
+        */
+       public static IWidgetInstance findWidgetInstance(String apiKey, String 
userId, String sharedDataKey, String widgetId, String serviceType) throws 
UnsupportedEncodingException{
+         IWidgetInstance instance;
+         IPersistenceManager persistenceManager = 
PersistenceManagerFactory.getPersistenceManager();
+         if (widgetId != null){
+           widgetId = URLDecoder.decode(widgetId, "UTF-8"); //$NON-NLS-1$
+           _logger.debug("Looking for widget instance with widgetid of " + 
widgetId);
+           instance = persistenceManager.findWidgetInstanceByGuid(apiKey, 
userId, sharedDataKey, widgetId);
+         } else {
+           _logger.debug("Looking for widget instance of service type " + 
serviceType);
+           instance = persistenceManager.findWidgetInstance(apiKey, userId, 
sharedDataKey, serviceType);
+         } 
+         return instance;
+       }
 }
\ No newline at end of file

Added: incubator/wookie/trunk/src/org/apache/wookie/helpers/MigrationHelper.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/helpers/MigrationHelper.java?rev=1176579&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/helpers/MigrationHelper.java 
(added)
+++ incubator/wookie/trunk/src/org/apache/wookie/helpers/MigrationHelper.java 
Tue Sep 27 19:58:11 2011
@@ -0,0 +1,116 @@
+/*
+ * 
+ * Licensed 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.wookie.helpers;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.wookie.beans.ISharedData;
+import org.apache.wookie.beans.IWidgetInstance;
+import org.apache.wookie.beans.util.IPersistenceManager;
+import org.apache.wookie.beans.util.PersistenceManagerFactory;
+import org.apache.wookie.controller.WidgetInstancesController;
+
+/**
+ * Migration Helper
+ * 
+ * This class provides helper methods for migrating from earlier versions of 
Wookie.
+ * 
+ * Note that this class and/or its methods may be deprecated in future 
releases.
+ */
+public class MigrationHelper {
+
+  /**
+   * Finds a widget instance using supplied parameters, using legacy shared 
data key generation methods. If an instance
+   * is found, the instance and any related resources are updated to use the 
current generation methods.
+   * @param apiKey
+   * @param userId
+   * @param sharedDataKey the shared data key, in its original external form
+   * @param widgetId
+   * @param serviceType
+   * @return the widget instance, or null if there is no match
+   * @throws UnsupportedEncodingException
+   */
+  public static IWidgetInstance findLegacyWidgetInstance(String apiKey, String 
userId, String sharedDataKey, String widgetId, String serviceType) throws 
UnsupportedEncodingException{
+    //
+    // Get shared data key using legacy method
+    //
+    String legacySharedDataKey = getLegacySharedDataKey(sharedDataKey);
+
+    //
+    // Find widget instance
+    //
+    IWidgetInstance instance = 
WidgetInstancesController.findWidgetInstance(apiKey, userId, 
legacySharedDataKey, widgetId, serviceType);
+
+    //
+    // Match found, so migrate the instance as well as any sibling instances 
that use the same shared data key, and any shared data instances
+    //
+    if (instance != null){  
+
+      //
+      // Get shared data key using current method
+      //
+      String internalSharedDataKey = 
SharedDataHelper.getInternalSharedDataKey(apiKey, widgetId, sharedDataKey);
+
+      //
+      // migrate instances and shared data using the legacy key to use new 
shared data hashcodes
+      //
+      migrateSharedDataKeys(legacySharedDataKey, internalSharedDataKey);
+    }
+    return instance;
+  }
+
+  /**
+   * Get the legacy version of the shared data key, from 0.9.0
+   * 
+   * @param externalSharedDataKey
+   * @return the legacy shared data key as a String
+   */
+  private static String getLegacySharedDataKey(String externalSharedDataKey){
+    String key = "null:"+externalSharedDataKey;
+    return String.valueOf(key.hashCode());
+  }
+
+  /**
+   * Migrate objects based on shared data keys
+   * 
+   * @param oldKey the old legacy shared data key
+   * @param newKey the new key to use as replacement
+   */
+  private static void migrateSharedDataKeys(String oldKey, String newKey){
+
+    //
+    // Locate instances using the old key and migrate to the new key
+    //
+    IPersistenceManager persistenceManager = 
PersistenceManagerFactory.getPersistenceManager();
+    IWidgetInstance[] widgetInstances = 
persistenceManager.findByValue(IWidgetInstance.class, "sharedDataKey", oldKey);
+    for (IWidgetInstance widgetInstance:widgetInstances){
+      widgetInstance.setSharedDataKey(newKey);
+      persistenceManager.save(widgetInstance);
+    }
+
+    //
+    // locate shared data objects using the old key and migrate to the new key
+    //
+    ISharedData[] sharedDataItems = 
persistenceManager.findByValue(ISharedData.class, "sharedDataKey", oldKey);
+    for (ISharedData sharedData: sharedDataItems){
+      sharedData.setSharedDataKey(newKey);
+      persistenceManager.save(sharedData);
+    }
+  }
+
+}


Reply via email to