Revision: 3471
Author: [email protected]
Date: Fri Apr 23 13:58:12 2010
Log: NEW - bug 2755: Do not allow changing the name of one user to a different existing user.
http://trillian.sqlpower.ca/bugzilla/show_bug.cgi?id=2755

To pass useful messages from the server there is now a 'friendly' version of a persistence exception. This type of exception can be thrown on the server to notify the user of a persistence exception and that it needs to roll back but it is not a critical error in the server so the user can continue to work. This is currently used to pass a 'username exists' type message but more uses will exist in the future. These types of exceptions will come up in friendly dialogs without red
text or a stack trace.
http://code.google.com/p/power-architect/source/detail?r=3471

Modified:
 /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONMessage.java
/trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONMessage.java Fri Mar 12 13:32:07 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONMessage.java Fri Apr 23 13:58:12 2010
@@ -19,13 +19,47 @@

 package ca.sqlpower.architect.enterprise;

+/**
+ * A class that holds JSON and other response values for a response from a
+ * server.
+ */
 public class JSONMessage {
     private final String message;
     private final boolean successful;

+    /**
+ * The status code of the response if it had one. If the response is just
+     * text this may be null.
+     */
+    private final Integer statusCode;
+
+    /**
+     * @param message
+ * The body of the response from the server. This may be but is
+     *            not limited to: an error message, exception, or JSON of
+     *            persist calls.
+     * @param successful
+     *            True if the response was successful, false otherwise.
+     */
     public JSONMessage(String message, boolean successful) {
+        this(message, successful, null);
+    }
+
+    /**
+     * @param message
+ * The body of the response from the server. This may be but is
+     *            not limited to: an error message, exception, or JSON of
+     *            persist calls.
+     * @param successful
+     *            True if the response was successful, false otherwise.
+     * @param statusCode
+ * The code that was returned in the response if the response
+     *            contained one.
+     */
+ public JSONMessage(String message, boolean successful, Integer statusCode) {
         this.message = message;
         this.successful = successful;
+        this.statusCode = statusCode;
     }

     public String getBody() {
@@ -35,4 +69,8 @@
     public boolean isSuccessful() {
         return successful;
     }
-}
+
+    public Integer getStatusCode() {
+        return statusCode;
+    }
+}
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java Tue Apr 6 10:20:51 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/JSONResponseHandler.java Fri Apr 23 13:58:12 2010
@@ -50,6 +50,12 @@
             while ((line = reader.readLine()) != null) {
                 buffer.append(line).append("\n");
             }
+
+            if (response.getStatusLine().getStatusCode() == 412) {
+                JSONObject message = new JSONObject(buffer.toString());
+ return new JSONMessage(message.getString("data"), false, 412);
+            }
+
             return handleResponse(buffer.toString());
         } catch (AccessDeniedException e) {
             throw e;
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Tue Apr 13 12:45:18 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java Fri Apr 23 13:58:12 2010
@@ -143,87 +143,107 @@
     private void flush(boolean reflush) {
         if (postingJSON.get() && !reflush) {
             return;
-        } else {
-            postingJSON.set(true);
-        }
-        // Try to send json message ...
-        JSONMessage response = null;
+        }
         try {
-            response = postJsonArray(messageBuffer.toString());
-        } catch (AccessDeniedException e) {
- List<UpdateListener> listenersToRemove = new ArrayList<UpdateListener>();
-            for (UpdateListener listener : updateListeners) {
- if (listener.updateException(NetworkConflictResolver.this)) {
-                    listenersToRemove.add(listener);
-                }
-            }
-            updateListeners.removeAll(listenersToRemove);
-            if (promptSession != null) {
-                promptSession.createUserPrompter(
- "You do not have sufficient privileges to perform that action. " + - "Please hit the refresh button to synchonize with the server.",
-                        UserPromptType.MESSAGE,
-                        UserPromptOptions.OK,
-                        UserPromptResponse.OK,
-                        "OK", "OK").promptUser("");
+            postingJSON.set(true);
+            // Try to send json message ...
+            JSONMessage response = null;
+            try {
+                response = postJsonArray(messageBuffer.toString());
+            } catch (AccessDeniedException e) {
+ List<UpdateListener> listenersToRemove = new ArrayList<UpdateListener>();
+                for (UpdateListener listener : updateListeners) {
+ if (listener.updateException(NetworkConflictResolver.this)) {
+                        listenersToRemove.add(listener);
+                    }
+                }
+                updateListeners.removeAll(listenersToRemove);
+                if (promptSession != null) {
+                    promptSession.createUserPrompter(
+ "You do not have sufficient privileges to perform that action. " + + "Please hit the refresh button to synchonize with the server.",
+                            UserPromptType.MESSAGE,
+                            UserPromptOptions.OK,
+                            UserPromptResponse.OK,
+                            "OK", "OK").promptUser("");
+                } else {
+                    throw e;
+                }
+                return;
+            }
+            if (response.isSuccessful()) {
+                // Sent json message without conflict.
+                try {
+ currentRevision = (new JSONObject(response.getBody())).getInt("currentRevision");
+                } catch (JSONException e) {
+ throw new RuntimeException("Could not update current revision" + e.getMessage());
+                }
+                // Prepare for next send ...
+                clear(reflush);
             } else {
-                throw e;
-            }
-            return;
-        }
-        if (response.isSuccessful()) {
-            // Sent json message without conflict.
-            try {
- currentRevision = (new JSONObject(response.getBody())).getInt("currentRevision");
-            } catch (JSONException e) {
- throw new RuntimeException("Could not update current revision" + e.getMessage());
-            }
-            // Prepare for next send ...
-            clear(reflush);
-        } else {
- // Did not successfully post json, we must update ourselves, and then try again if we can.
-            if (!reflush) {
- // These lists should reflect the state of the workspace at the time of the conflict. - // The workspace could be updated several times before a successful post is made.
-                fillOutboundPersistedLists();
-            }
-            // Try to rollback our changes
-            try {
- session.getWorkspace().rollback("Hello this is a rollback");
-            } catch (Exception e) {
- throw new RuntimeException("Reflush failed on rollback", e);
-            }
-            String json;
-            int newRev;
-            try {
-                JSONObject jsonObject = new JSONObject(response.getBody());
-                json = jsonObject.getString("data");
-                newRev = jsonObject.getInt("currentRevision");
-            } catch (Exception e) {
-                throw new RuntimeException("Reflush failed on getJson", e);
-            }
- // Try to create inboundPersistedLists for comparison with the outbound. These will be used
-            // for special case collision detection.
-            fillInboundPersistedLists(json);
-            // Try to apply update
-            decodeMessage(json, newRev);
- // We need an additional step here for checking for special case conflicts
-            if (detectConflict()) {
- throw new RuntimeException("There is a conflict between our state and the server's, our changes will be lost");
-            } else {
- // Try to return the persisted objects to their state pre-update. + // Did not successfully post json, we must update ourselves, and then try again if we can.
+                if (!reflush) {
+ // These lists should reflect the state of the workspace at the time of the conflict. + // The workspace could be updated several times before a successful post is made.
+                    fillOutboundPersistedLists();
+                }
+                // Try to rollback our changes
                 try {
- SPSessionPersister.redoForSession(session.getWorkspace(), - outboundObjectsToAdd, outboundPropertiesToChange,
-                            outboundObjectsToRemove, converter);
- // We want to re-send our changes, but only if we were able to restore them
-                    flush(true);
-                } catch (Exception ex) {
- throw new RuntimeException("Reflush failed on rollforward", ex); + session.getWorkspace().rollback("Hello this is a rollback");
+                } catch (Exception e) {
+ throw new RuntimeException("Reflush failed on rollback", e);
+                }
+
+ //If the preconditions failed which caused the persist to fail don't try to
+                //push the persist forward again.
+ if (!response.isSuccessful() && new Integer(412).equals(response.getStatusCode())) {
+                    logger.info("Friendly error occurred, " + response);
+                    if (promptSession != null) {
+                        promptSession.createUserPrompter(
+                                response.getBody(),
+                                UserPromptType.MESSAGE,
+                                UserPromptOptions.OK,
+                                UserPromptResponse.OK,
+                                "OK", "OK").promptUser("");
+                    } else {
+ logger.warn("Missing a prompt session! Message was " + response);
+                    }
+                    return;
+                }
+
+                String json;
+                int newRev;
+                try {
+ JSONObject jsonObject = new JSONObject(response.getBody());
+                    json = jsonObject.getString("data");
+                    newRev = jsonObject.getInt("currentRevision");
+                } catch (Exception e) {
+ throw new RuntimeException("Reflush failed on getJson", e);
+                }
+ // Try to create inboundPersistedLists for comparison with the outbound. These will be used
+                // for special case collision detection.
+                fillInboundPersistedLists(json);
+                // Try to apply update
+                decodeMessage(json, newRev);
+ // We need an additional step here for checking for special case conflicts
+                if (detectConflict()) {
+ throw new RuntimeException("There is a conflict between our state and the server's, our changes will be lost");
+                } else {
+ // Try to return the persisted objects to their state pre-update.
+                    try {
+ SPSessionPersister.redoForSession(session.getWorkspace(), + outboundObjectsToAdd, outboundPropertiesToChange,
+                                outboundObjectsToRemove, converter);
+ // We want to re-send our changes, but only if we were able to restore them
+                        flush(true);
+                    } catch (Exception ex) {
+ throw new RuntimeException("Reflush failed on rollforward", ex);
+                    }
                 }
             }
-        }
-        postingJSON.set(false);
+        } finally {
+            postingJSON.set(false);
+        }
     }

     public void clear() {


--
Subscription settings: 
http://groups.google.com/group/architect-commits/subscribe?hl=en

Reply via email to