Author: ivol37 at gmail.com
Date: Wed Dec 22 12:49:49 2010
New Revision: 529

Log:
[AMDATU-222] Added "Group" tab to manage groups. Fixed proper encoding of role 
names. Still TODO: basic authorization, assigning users to groups, 
multi-language support

Added:
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
      - copied, changed from r522, 
/trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/UserBean.java
Removed:
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/UserBean.java
Modified:
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/useradmin.css
   
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
   
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
      (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/jsp/UserAdminGadget.jsp
      Wed Dec 22 12:49:49 2010
@@ -2,7 +2,8 @@
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"; %>
 
 <c:set var="baseUrl" 
value="http://${pageContext.request.serverName}:${pageContext.request.serverPort}"/>
-<c:set var="restUrl" value="${baseUrl}/rest/services/users/users"/>
+<c:set var="restUrl" value="${baseUrl}/rest/services"/>
+
 <c:set var="gadgetBaseUrl" value="${baseUrl}/gadget/useradmin"/>
 <c:set var="imgBaseUrl" value="${baseUrl}/gadget/useradmin/static/images" />
 <c:set var="jsBaseUrl" value="${baseUrl}/gadget/useradmin/static/js" />
@@ -11,8 +12,8 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <Module>
   <ModulePrefs 
-    title="Amdatu User Admin Gadget" 
-    description="User and Group management"
+    title="Amdatu Role Admin Gadget" 
+    description="Role and Group management"
     author="Ivo Ladage-van Doorn"
     screenshot="${gadgetBaseUrl}/static/images/useradmin.png"
     icon="${gadgetBaseUrl}/static/images/useradmin.png" 
@@ -24,38 +25,74 @@
     <![CDATA[
     <link rel="stylesheet" href="/dashboard/static/css/dashboard.css">
     <link rel="stylesheet" href="${cssBaseUrl}/useradmin.css">
+    <link rel="stylesheet" href="${cssBaseUrl}/tabs.css" type="text/css" 
media="screen" />
     
     <script type="text/javascript" 
src="/dashboard/static/js/lib/jquery-1.4.2.min.js"></script>
     <script type="text/javascript" 
src="/dashboard/static/js/lib/jquery-ui-1.8.2.custom.min.js"></script>
     <script type="text/javascript" 
src="${jsBaseUrl}/useradmin_rest.js"></script>
+    <script type="text/javascript" src="${jsBaseUrl}/tabs.js"></script>
     
     <p>
-      <div id="users"></div>
-      
-      <hr/>
-      
-      <input type="button" value="Add user" id="adduserbutton" 
onclick="javascript:showNewUser();"/>
-      
-      <fieldset id="details" style="display:none;visibility:hidden">
-        <legend id="details_legend">Details</legend>
-          <table width="95%">
-            <tr><td>Username</td><td><input type="edit" id="username" value="" 
disabled="disabled"/></td></tr>
-            <tr><td id="password_label">New password</td><td><input 
type="password" id="password" value="" 
onkeyup="javascript:validatePassword();"/></td></tr>
-          </table>
-          <input type="submit" id="save" value="Save" 
onclick="javascript:saveUser();" disabled="disabled"/>
-          <input type="button" value="Cancel" 
onclick="javascript:showAddButton();"/>
-          <input type="hidden" id="method" value="update"/>
-          <div id="message"></div>
-      </fieldset>
-      
+      <div id="container">
+        <ul class="menu">
+          <li id="users_tab" class="active">Users</li>
+          <li id="groups_tab">Groups</li>
+        </ul>
+        
+        <span class="clear"></span>
+        
+        <div class="content users_tab">
+          <div id="users"></div><br/>
+          
+          <input type="button" value="Add user" id="add_user_button" 
onclick="javascript:showNewRole();"/>
+
+          <fieldset id="user_details" style="display:none;visibility:hidden">
+            <legend id="user_details_legend">Details</legend>
+              <table width="95%">
+                <tr><td>Username</td><td><input type="edit" id="user_name" 
value="" disabled="disabled" 
onkeyup="javascript:validateNonEmpty('user_name');"/></td></tr>
+                <tr><td id="password_label">New password</td><td><input 
type="password" id="password" value="" 
onkeyup="javascript:validateNonEmpty('password');"/></td></tr>
+              </table>
+              <input type="submit" id="user_save" value="Save" 
onclick="javascript:saveRole();" disabled="disabled"/>
+              <input type="button" value="Cancel" 
onclick="javascript:showAddButton();"/>
+              <input type="hidden" id="user_method" value="update"/>
+              <div id="user_message"></div>
+          </fieldset>          
+        </div>
+        
+        <div class="content groups_tab">
+          <div id="groups"></div><br/>
+          
+          <input type="button" value="Add group" id="add_group_button" 
onclick="javascript:showNewRole();"/>
+          
+          <fieldset id="group_details" style="display:none;visibility:hidden">
+            <legend id="group_details_legend">Details</legend>
+              <table width="95%">
+                <tr><td>Group name</td><td><input type="edit" id="group_name" 
value="" disabled="disabled" 
onkeyup="javascript:validateNonEmpty('group_name');"/></td></tr>
+              </table>
+              <input type="submit" id="group_save" value="Save" 
onclick="javascript:saveRole();" disabled="disabled"/>
+              <input type="button" value="Cancel" 
onclick="javascript:showAddButton();"/>
+              <input type="hidden" id="group_method" value="update"/>
+              <div id="group_message"></div>
+          </fieldset>
+          <br/>
+        </div>
+      </div>
+    </p>
     
     <script type="text/javascript"> 
-      // Callback function invoked when users have been loaded
-      function onUsersLoaded(response) {
+      var restUrl = "${restUrl}/users/users?maxResults=5";
+      var currentUrl;
+      var currentUsersUrl;
+      var currentGroupsUrl;
+      var id = "users";
+      
+      // Callback function invoked when roles have been loaded
+      function onRolesLoaded(response) {
         var jsonData = response.data["searchresult"];
         var pageStartIndex = jsonData["pageStartIndex"];
         var pageEndIndex = jsonData["pageEndIndex"];
         var resultCount = jsonData["resultCount"];
+        var pageCount = jsonData["pageCount"];
         
         var links = jsonData["links"];
         for (i=0; i<links.length; i++) {
@@ -67,34 +104,50 @@
              var next = getImageLink("next.gif", links[i]["href"]);
           } else if (links[i]["rel"] == "End") {
              var end = getImageLink("end.gif", links[i]["href"]);
+          } else if (links[i]["rel"] == "Alternate") {
+             currentUrl = "${baseUrl}" + links[i]["href"];
+             if (id == "users") {
+              currentUsersUrl = currentUrl;
+             } else {
+              currentGroupsUrl = currentUrl;
+             }
           } 
         }
         
         var html = "";
         
         // First add the table header
-        var users = jsonData["users"];
-        if (users) {
+        var roles = jsonData["roles"];
+        if (pageCount == 1) {
+          roles = new Array();
+          roles[0] = jsonData["roles"];
+        }
+        if (roles) {
           html += "<table class='stripeMe'>";
-          html += "<tr><th>Username</th><th>Delete</th></tr>";    
-          for (i=0; i<users.length; i++) {
-            var user = users[i];
-            var link = user["link"].href;
-            var editUser = " onclick=\"javascript:editUser('" + link + "');\"";
-            var deleteUser = " onclick=\"javascript:confirmDeleteUser('" + 
link + "', '" + user["name"] + "');\"";
-            html += "<tr><td><a href='#'" + editUser + ">" + user["name"] + 
"</a></td>";
-            html += "<td align='center'><a href='#'" + deleteUser + "><img 
src='/gadget/useradmin/static/images/remove.gif'/></a></td></tr>";
+          html += "<tr><th width='80%'>" + id + " name</th><th 
width='20%'>Delete</th></tr>";    
+          for (i=0; i<roles.length; i++) {
+            var role = roles[i];
+            var link = role["link"].href;
+            var editRole = " onclick=\"javascript:editRole('" + escape(link) + 
"');\"";
+            var deleteRole = " onclick=\"javascript:confirmDeleteRole('" + 
escape(link) + "', '" + escape(role["name"]) + "');\"";
+            html += "<tr><td><a href='#'" + editRole + ">" + role["name"] + 
"</a></td>";
+            html += "<td align='center'><a href='#'><img 
src='/gadget/useradmin/static/images/remove.gif'" + deleteRole + 
"/></a></td></tr>";
           }
           html += "</table></center></p>";
         }
         html += "<p><center><table><tr>";
         html += "<td>" + start + "</td>";
         html += "<td>" + prev + "</td>";
-        html += "<td>Displaying results <b>" + pageStartIndex + "-" + 
pageEndIndex + "<b> of <b>" + resultCount + "</b></td>";
+        html += "<td><center>Displaying results <b>" + pageStartIndex + "-" + 
pageEndIndex + "<b> of <b>" + resultCount + "</b></center></td>";
         html += "<td>" + next + "</td>";
         html += "<td>" + end + "</td></table>"; 
         
-        var resultDiv = document.getElementById("users");
+        var resultDiv;
+        if (currentView == "users") {
+          resultDiv = document.getElementById("users");
+        } else {
+          resultDiv = document.getElementById("groups");
+        }
         resultDiv.innerHTML = html;
         
         // make the table zebra-style
@@ -102,19 +155,17 @@
         $(".stripeMe tr").mouseout(function() {$(this).removeClass("over");});
         $(".stripeMe tr:even").addClass("alt");
 
-        $("div.users").wrap("<fieldset><legend>User</legend></fieldset>");
-
         gadgets.window.adjustHeight();
       }          
       
-      // Callback function invoked when one specific user details have been 
loaded
-      function onUserLoaded(response) {
+      // Callback function invoked when one specific role details have been 
loaded
+      function onRoleLoaded(response) {
         if (response.rc == 200) {
-          var user = response.data["users"];  
-          document.getElementById('username').value = user["name"];
+          var role = response.data["roles"];  
+          document.getElementById(id + '_name').value = role["name"];
           gadgets.window.adjustHeight();
          } else if (response.rc == 404) {
-          showError("User could not be found.");
+          showError("Role could not be found.");
         } else {
           showError(response.errors);
         }   
@@ -125,30 +176,30 @@
         if (response.rc == 200) {
           showInfo('Password changed successfully');
         } else if (response.rc == 404) {
-          showError("User to update credential for could not be found.");
+          showError("Role to update credential for could not be found.");
         } else {
           showError(response.errors);
         } 
       }
       
-      // Callback function invoked when the the user has been removed
-      function onUserDeleted(response) {
+      // Callback function invoked when the the role has been removed
+      function onRoleDeleted(response) {
         if (response.rc == 200) {
-          // User added successfully
-          loadUsers("${restUrl}?maxResults=5", onUsersLoaded);
+          // Role added successfully
+          loadRoles(currentUrl, onRolesLoaded);
           gadgets.window.adjustHeight();
         } else if (response.rc == 304) {
-          showError("User to delete could not be found.");
+          alert("Role to delete could not be found.");
         } else {
-          showError(response.errors);
+          alert("An error occurred while removing role: " + response.errors);
         } 
       }
       
-      function onUserAdded(response) {
+      function onRoleAdded(response) {
         if (response.rc == 200) {
-          // User added successfully
-          showInfo('User added successfully');
-          loadUsers("${restUrl}?maxResults=5", onUsersLoaded);
+          // Role added successfully
+          showInfo('Role added successfully');
+          loadRoles(currentUrl, onRolesLoaded);
           gadgets.window.adjustHeight();
         } else if (response.rc == 304) {
           showError("A user with this name already exists.");
@@ -157,88 +208,102 @@
         }    
       }
       
-      function saveUser() {
-        var method = document.getElementById("method").value;
-        var username = document.getElementById("username").value;
-        var newpassword = document.getElementById('password').value
-        var url = "${baseUrl}/rest/services/users/users/" + username;
-        if (method == "update") {
-          url += "/credentials/password";
-          updatePassword(url, onPasswordChanged, newpassword);
+      function saveRole() {
+        var method = document.getElementById(id + "_method").value;
+        var name = encodeURIComponent(document.getElementById(id + 
"_name").value);
+        
+        if (id == "users") {
+          var newpassword = document.getElementById('password').value
+          var url = "${baseUrl}/rest/services/users/users/" + name;
+          if (method == "update") {
+            url += "/credentials/password";
+            updatePassword(url, onPasswordChanged, newpassword);
+          } else {
+            addRole(url, onRoleAdded);
+          }
         } else {
-          addUser(url, onUserAdded);
+          var url = "${baseUrl}/rest/services/groups/groups/" + name;
+          addRole(url, onRoleAdded);
         }
       }
       
-      function validatePassword() {
-        if (document.getElementById("password").value != "") {
-          document.getElementById("save").disabled = "";
+      function validateNonEmpty(fieldId) {
+        if (document.getElementById(fieldId).value != "") {
+          document.getElementById(id + "_save").disabled = "";
         } else {
-          document.getElementById("save").disabled = "disabled";
+          document.getElementById(id + "_save").disabled = "disabled";
         }
       }
       
       function getImageLink(image, href) {
-        var result = "<img src='${imgBaseUrl}/" + image + "' 
onClick='javascript:loadUsers(\"${baseUrl}" + href + "\", onUsersLoaded)'/>";
+        var result = "<a href='#'><img src='${imgBaseUrl}/" + image + "' 
onClick='javascript:loadRoles(\"${baseUrl}" + href + "\", 
onRolesLoaded)'/></a>";
         return result;
       }
       
-      function editUser(link) {
-        loadUser('${baseUrl}' + link, onUserLoaded);
-        showEditUser();
+      function editRole(link) {
+        loadRole(escape('${baseUrl}' + unescape(link)), onRoleLoaded);
+        showEditRole();
       }
       
-      function confirmDeleteUser(link, username) {
-        if (confirm('Are you sure you want to delete "' + username + '"?')) {
-          deleteUser('${baseUrl}' + link, onUserDeleted);
+      function confirmDeleteRole(link, name) {
+        if (confirm('Are you sure you want to delete "' + unescape(name) + 
'"?')) {
+          deleteRole(escape('${baseUrl}' + unescape(link)), onRoleDeleted);
         }
       }
       
       function showInfo(msg) {
         if (msg != "") {
-          document.getElementById('message').innerHTML = "<p><font 
color='green'>" + msg + "</font></p>";
+          document.getElementById(id + '_message').innerHTML = "<p><font 
color='green'>" + msg + "</font></p>";
         } else {
-          document.getElementById('message').innerHTML = "";
+          document.getElementById(id + '_message').innerHTML = "";
         }
         gadgets.window.adjustHeight();
       }
       
       function showError(msg) {
         if (msg != "") {
-          document.getElementById('message').innerHTML = "<p><font 
color='red'>" + msg + "</font></p>";
+          document.getElementById(id + '_message').innerHTML = "<p><font 
color='red'>" + msg + "</font></p>";
         } else {
-          document.getElementById('message').innerHTML = "";
+          document.getElementById(id + '_message').innerHTML = "";
         }
         gadgets.window.adjustHeight();
       }
       
       function showAddButton() {
-        show('adduserbutton');
-        hide('details');
+        show('add_' + id + '_button');
+        hide(id + '_details');
         gadgets.window.adjustHeight();
       }
       
-      function showNewUser() {
-        document.getElementById('details_legend').innerHTML = "New user";
-        document.getElementById('password_label').innerHTML = "Password";
-        document.getElementById('username').value = "";
-        document.getElementById('username').disabled = "";
-        document.getElementById('password').value = "";
-        document.getElementById('method').value = "add";
+      function showNewRole() {
+        document.getElementById(id + '_details_legend').innerHTML = "New " + 
id;
+        document.getElementById(id + '_name').value = "";
+        document.getElementById(id + '_name').disabled = "";
+        document.getElementById(id + '_method').value = "add";
+        
+        if (id == "users") {
+          document.getElementById('password_label').innerHTML = "Password";
+          document.getElementById('password').value = "";
+        }
+        
         showError("");
-        show('details');
-        hide('adduserbutton');
+        show(id + '_details');
+        hide('add_' + id + '_button');
         gadgets.window.adjustHeight();
       }
       
-      function showEditUser() {
-       document.getElementById('details_legend').innerHTML = "User details";
-        document.getElementById('password_label').innerHTML = "New password";
-        document.getElementById('username').disabled = "disabled";
-        document.getElementById('method').value = "update";
+      function showEditRole() {
+        document.getElementById(id + '_details_legend').innerHTML = id + " 
details";
+        document.getElementById(id + '_name').disabled = "disabled";
+        document.getElementById(id + '_method').value = "update";
+ 
+        if (id == "users") {
+          document.getElementById('password_label').innerHTML = "New password";
+        } 
+        
         showError("");
-        show('details');
-        hide('adduserbutton');
+        show(id + '_details');
+        hide('add_' + id + '_button');
         gadgets.window.adjustHeight();
       }
       
@@ -254,8 +319,22 @@
         obj.style.display = "none";
       }
       
+      function switchToUsersView() {
+        restUrl = "${restUrl}/users/users?maxResults=5";
+        id = "user";
+        currentUrl = currentUsersUrl;
+        loadRoles(restUrl, onRolesLoaded);
+      }
+      
+      function switchToGroupsView() {
+        restUrl = "${restUrl}/groups/groups?maxResults=5";
+        id = "group";
+        currentUrl = currentGroupsUrl;
+        loadRoles(restUrl, onRolesLoaded);
+      }
+      
       $(document).ready(function(){
-        loadUsers("${restUrl}?maxResults=5", onUsersLoaded);
+        loadRoles(restUrl, onRolesLoaded);
       });
       
     </script>

Added: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/tabs.css
  Wed Dec 22 12:49:49 2010
@@ -0,0 +1,66 @@
+ at CHARSET "UTF-8";
+/******* GENERAL RESET *******/
+html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, 
blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
+font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, 
dt, dd, ol, ul, li {
+border:0pt none;
+margin:0pt;
+padding:0pt;
+vertical-align:baseline;
+}
+
+.clear{
+  clear: both;
+  height: 0;
+  visibility: hidden;
+  display: block;
+}
+
+/******* MENU *******/
+#container{
+  width: 95%;
+  border: 0px;
+}
+#container ul{
+  list-style: none;
+  list-style-position: outside;
+}
+#container ul.menu li{
+  float: left;
+  margin-right: 5px;
+  margin-bottom: -1px;
+}
+#container ul.menu li{
+  font-weight: 700;
+  display: block;
+  padding: 5px 10px 5px 10px;
+  background: #efefef;
+  margin-bottom: -1px;
+  border: 1px solid #d0ccc9;
+  border-width: 1px 1px 1px 1px;
+  position: relative;
+  color: #898989;
+  cursor: pointer;
+}
+#container ul.menu li.active{
+  background: #fff;
+  top: 1px;
+  border-bottom: 0;
+  color: #5f95ef;
+}
+/******* /MENU *******/
+/******* CONTENT *******/
+.content{
+  margin: 0pt auto;
+  border: 1px solid #d0ccc9;
+  text-align: left;
+  padding: 10px;
+  padding-bottom: 10px;
+}
+
+.content.users_tab{
+  display: block;
+}
+
+.content.groups_tab{
+  display: none;
+}

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/useradmin.css
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/useradmin.css
     (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/css/useradmin.css
     Wed Dec 22 12:49:49 2010
@@ -2,13 +2,13 @@
   background: #fff;
 }
 
-table {
+table.stripeMe {
   border-collapse: collapse;
   font-size: 1.1em;
   width: 100%;
 }
 
-th {
+table.stripeMe th {
   background: #3e83c9;
   color: #fff;
   font-weight: bold;
@@ -18,20 +18,33 @@
   line-height: 1.2;
 }
 
-td {
+table.stripeMe td {
   padding: 2px 1px;
   border-bottom: 1px solid #95bce2;
   vertical-align: top;
 }
 
-td * {
+table.stripeMe td * {
   padding: 2px 1px;
+  valign: center;
 }
 
-tr.alt td {
+table.stripeMe tr.alt td {
   background: #ecf6fc;
 }
 
-tr.over td {
+table.stripeMe tr.over td {
   background: #bcd4ec;
 }
+
+fieldset {
+  border: 1px solid #d0ccc9;
+}
+
+fieldset legend {
+  font-size: 0.8em;
+}
+
+img.mouseover  {
+  cursor:hand;
+}

Added: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/tabs.js
    Wed Dec 22 12:49:49 2010
@@ -0,0 +1,36 @@
+/***************************/
+//@Author: Adrian "yEnS" Mato Gondelle & Ivan Guardado Castro
+//@website: www.yensdesign.com
+//@email: yensamg at gmail.com
+//@license: Feel free to use it, but keep this credits please!          
+/***************************/
+
+var currentView = "users";
+
+$(document).ready(function(){
+  $(".menu > li").click(function(e){
+    switch(e.target.id){
+      case "users_tab":
+        //change status & style menu
+        $("#users_tab").addClass("active");
+        $("#groups_tab").removeClass("active");
+        //display selected division, hide others
+        $("div.users_tab").fadeIn();
+        $("div.groups_tab").css("display", "none");
+        currentView = "users";
+        switchToUsersView();
+      break;
+      case "groups_tab":
+        //change status & style menu
+        $("#users_tab").removeClass("active");
+        $("#groups_tab").addClass("active");
+        //display selected division, hide others
+        $("div.groups_tab").fadeIn();
+        $("div.users_tab").css("display", "none");
+        currentView = "groups";
+        switchToGroupsView();
+      break;
+    }
+    return false;
+  });
+});
\ No newline at end of file

Modified: 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
  (original)
+++ 
trunk/amdatu-authorization/useradmin-gadget/src/main/resources/static/js/useradmin_rest.js
  Wed Dec 22 12:49:49 2010
@@ -1,5 +1,5 @@
-// Loads users and invokes the callback function with the result
-function loadUsers(url, callback) {
+// Loads roles and invokes the callback function with the result
+function loadRoles(url, callback) {
   var params = {};
   params[gadgets.io.RequestParameters.CONTENT_TYPE] = 
gadgets.io.ContentType.JSON;
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
@@ -7,12 +7,12 @@
   gadgets.io.makeRequest(url, callback, params);
 }
 
-// Loads one specific user and invokes the callback function with the result
-function loadUser(url, callback) {
+// Loads one specific role and invokes the callback function with the result
+function loadRole(url, callback) {
   var params = {};
   params[gadgets.io.RequestParameters.CONTENT_TYPE] = 
gadgets.io.ContentType.JSON;
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
-  url = addNoCache(url);  
+  url = addNoCache(unescape(url));  
   gadgets.io.makeRequest(url, callback, params);
 }
 
@@ -27,20 +27,20 @@
   gadgets.io.makeRequest(url, callback, params);
 }
 
-// Adds a new user
- function addUser(url, callback) {
+// Adds a new role
+ function addRole(url, callback) {
   var params = {};
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.PUT;
   url = addNoCache(url);  
   gadgets.io.makeRequest(url, callback, params);
 }
       
-// Deletes the specified user
-function deleteUser(url, callback) {
+// Deletes the specified role
+function deleteRole(url, callback) {
   var params = {};
   params[gadgets.io.RequestParameters.CONTENT_TYPE] = 
gadgets.io.ContentType.JSON;
   params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.DELETE;
-  url = addNoCache(url);
+  url = addNoCache(unescape(url));
   gadgets.io.makeRequest(url, callback, params);
 }
 

Copied: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
 (from r522, 
/trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/UserBean.java)
==============================================================================
--- 
/trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/UserBean.java
 (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/RoleBean.java
  Wed Dec 22 12:49:49 2010
@@ -16,6 +16,12 @@
  */
 package org.amdatu.authorization.useradmin.rest.bean;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+
+import javax.ws.rs.core.UriBuilder;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
@@ -24,19 +30,18 @@
 
 import org.amdatu.libraries.utilities.rest.AtomSyndicationLink;
 import org.osgi.service.useradmin.Role;
-import org.osgi.service.useradmin.User;
 
 @SuppressWarnings("restriction")
- at XmlRootElement(name = "users")
+ at XmlRootElement(name = "roles")
 @XmlAccessorType(XmlAccessType.NONE)
-public class UserBean {
+public class RoleBean {    
     @XmlAttribute(name = "name")
     private String m_name;
 
     @XmlElement(name = "link")
     private AtomSyndicationLink m_link;
 
-    public UserBean() {
+    public RoleBean() {
     }
 
     public String getName() {
@@ -55,12 +60,19 @@
         m_link = link;
     }
 
-    public static UserBean fromRole(Role role) {
-        UserBean user = new UserBean();
-        String name = ((User) role).getName();
-        user.setName(name);
-        String href = "/rest/services/users/users/" + name;
-        user.setLink(new 
AtomSyndicationLink().setHref(href).setRel("Alternate").setType("application/json"));
-        return user;
+    public static RoleBean fromRole(Role role) throws URISyntaxException {
+        RoleBean roleBean = new RoleBean();
+        String name = role.getName();
+        roleBean.setName(name);
+        String href = "/rest/services/";
+        if (role.getType() == Role.USER) {
+            href += "users/users/" + name;
+        } else {
+            href += "groups/groups/" + name;
+        }
+        // Use JAX-RS URI builder to properly encode the href
+        href = UriBuilder.fromPath(href).build().toString();
+        roleBean.setLink(new 
AtomSyndicationLink().setHref(href).setRel("Alternate").setType("application/json"));
+        return roleBean;
     }
 }

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
  (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/bean/SearchResultBean.java
  Wed Dec 22 12:49:49 2010
@@ -16,6 +16,7 @@
  */
 package org.amdatu.authorization.useradmin.rest.bean;
 
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -30,6 +31,9 @@
 @XmlRootElement(name = "searchresult")
 @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
 public class SearchResultBean {
+    // Default encoding for role properties
+    public final static String DEFAULT_CHARSET = "UTF-8";
+    
     // Atom links
     private List<AtomSyndicationLink> m_links = new 
ArrayList<AtomSyndicationLink>();
 
@@ -43,7 +47,7 @@
     private int m_resultCount;
     
     // The actual results
-    private List<UserBean> m_users = new ArrayList<UserBean>();
+    private List<RoleBean> m_roles = new ArrayList<RoleBean>();
 
     public int getPageStartIndex() {
         return m_pageStartIndex;
@@ -97,18 +101,18 @@
         m_links.add(link);
     }
 
-    public List<UserBean> getUsers() {
-        return m_users;
+    public List<RoleBean> getRoles() {
+        return m_roles;
     }
 
-    public void setUsers(List<UserBean> users) {
-        m_users = users;
+    public void setRoles(List<RoleBean> users) {
+        m_roles = users;
     }
     
-    public void addUsers(List<Role> users) {
-        for (Role role : users) {
-            UserBean user = UserBean.fromRole(role);
-            m_users.add(user);
+    public void addRoles(List<Role> roles) throws URISyntaxException {
+        for (Role role : roles) {
+            RoleBean roleBean = RoleBean.fromRole(role);
+            m_roles.add(roleBean);
         }
     }
 }

Modified: 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
==============================================================================
--- 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
   (original)
+++ 
trunk/amdatu-authorization/useradmin-rest/src/main/java/org/amdatu/authorization/useradmin/rest/service/ResourceBase.java
   Wed Dec 22 12:49:49 2010
@@ -16,17 +16,19 @@
  */
 package org.amdatu.authorization.useradmin.rest.service;
 
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.CacheControl;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.amdatu.authorization.useradmin.rest.bean.RoleBean;
 import org.amdatu.authorization.useradmin.rest.bean.SearchResultBean;
-import org.amdatu.authorization.useradmin.rest.bean.UserBean;
 import org.amdatu.libraries.utilities.rest.AtomSyndicationLink;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -102,7 +104,7 @@
             }
 
             SearchResultBean result = new SearchResultBean();
-            result.addUsers(roleRange);
+            result.addRoles(roleRange);
 
             // Calculate paging
             Paging paging = new Paging();
@@ -115,26 +117,39 @@
             debugMsg += "    End page=" + paging.lastStartIndex + "-" + 
paging.lastEndIndex;
             m_logService.log(LogService.LOG_DEBUG, debugMsg);
 
-            // Set the 4 Atom links first, previous, next and start
+            // Set the 5 Atom links current, first, previous, next and start
             String url = "";
+
+            // Start
+            url =
+                getBaseUrl() + "?startIndex=" + paging.pageStartIndex + 
"&endIndex=" + paging.pageEndIndex
+                + "&maxResults=" + maxResults;
+            result.addLink(new 
AtomSyndicationLink().setHref(url).setRel("Alternate").setType("application/json"));
             
             // Start
-            url = getBaseUrl() + "?startIndex=" + paging.firstStartIndex + 
"&endIndex=" + paging.firstEndIndex + "&maxResults=" + maxResults;
+            url =
+                getBaseUrl() + "?startIndex=" + paging.firstStartIndex + 
"&endIndex=" + paging.firstEndIndex
+                + "&maxResults=" + maxResults;
             result.addLink(new 
AtomSyndicationLink().setHref(url).setRel("Start").setType("application/json"));
 
             // Prev
-            url = getBaseUrl() + "?startIndex=" + paging.previousStartIndex + 
"&endIndex=" + paging.previousEndIndex + "&maxResults=" + maxResults;
+            url =
+                getBaseUrl() + "?startIndex=" + paging.previousStartIndex + 
"&endIndex=" + paging.previousEndIndex
+                + "&maxResults=" + maxResults;
             result.addLink(new 
AtomSyndicationLink().setHref(url).setRel("Prev").setType("application/json"));
 
             // Next
-            url = getBaseUrl() + "?startIndex=" + paging.nextStartIndex + 
"&endIndex=" + paging.nextEndIndex + "&maxResults=" + maxResults;
+            url =
+                getBaseUrl() + "?startIndex=" + paging.nextStartIndex + 
"&endIndex=" + paging.nextEndIndex
+                + "&maxResults=" + maxResults;
             result.addLink(new 
AtomSyndicationLink().setHref(url).setRel("Next").setType("application/json"));
-            
+
             // Last
-            url = getBaseUrl() + "?startIndex=" + paging.lastStartIndex + 
"&endIndex=" + paging.lastEndIndex + "&maxResults=" + maxResults;
+            url =
+                getBaseUrl() + "?startIndex=" + paging.lastStartIndex + 
"&endIndex=" + paging.lastEndIndex
+                + "&maxResults=" + maxResults;
             result.addLink(new 
AtomSyndicationLink().setHref(url).setRel("End").setType("application/json"));
 
-            
             result.setPageMax(paging.pageMax);
             result.setPageStartIndex(paging.pageStartIndex);
             result.setPageEndIndex(paging.pageEndIndex);
@@ -147,14 +162,24 @@
             m_logService.log(LogService.LOG_ERROR, "Unable to retrieve roles 
for filter '" + filter + "', startIndex '"
                 + startIndex + "' maxResults '" + maxResults + "'", e);
         }
+        catch (URISyntaxException e) {
+            m_logService.log(LogService.LOG_ERROR, "Could not URL encode role 
name", e);
+            throw new WebApplicationException(e);
+        }
         return buildServerError();
     }
 
     protected Response getRole(String name, int roleType) {
         Role role = m_userAdmin.getRole(name);
         if (role != null && role.getType() == roleType) {
-            UserBean user = UserBean.fromRole(role);
-            return Response.ok(user).cacheControl(m_cacheControl).build();
+            try {
+                RoleBean user = RoleBean.fromRole(role);
+                return Response.ok(user).cacheControl(m_cacheControl).build();
+            }
+            catch (URISyntaxException e) {
+                m_logService.log(LogService.LOG_ERROR, "Could not URL encode 
role name '" + name + "'", e);
+                throw new WebApplicationException(e);
+            }
         }
         else {
             return buildNotFound();
@@ -265,7 +290,7 @@
         int pageCount; // Amount of results displayed on current page
         int pageMax; // Maximum number of results displayed on one page
         int resultCount; // Total amount of available results;
-        
+
         int firstStartIndex; // Start index of first page
         int firstEndIndex; // Last index of first page
         int previousStartIndex; // // Start index of previous page
@@ -277,6 +302,7 @@
 
         /**
          * Calculate paging
+         * 
          * @param currentStartIndex The requested start index to display
          * @param pageResults The amount of results in the current selection
          * @param maxResults The maximum amount of results displayed on one 
page
@@ -288,20 +314,21 @@
             pageMax = maxResults;
             pageStartIndex = pageResults > 0 ? Math.max(1, currentStartIndex) 
: 0;
             pageEndIndex = pageStartIndex + (pageResults - 1);
-            
+
             // Calculate first page
             firstStartIndex = pageResults > 0 ? 1 : 0;
             firstEndIndex = Math.min(pageResults, maxResults);
-            
+
             // Calculate previous page
             if (currentStartIndex - maxResults < firstStartIndex) {
                 previousStartIndex = firstStartIndex;
                 previousEndIndex = firstEndIndex;
-            } else {
+            }
+            else {
                 previousStartIndex = currentStartIndex - maxResults;
                 previousEndIndex = currentStartIndex - 1;
             }
-            
+
             // Calculate last page
             if (totalResults % maxResults == 0) {
                 lastStartIndex = Math.max(0, totalResults - maxResults + 1);
@@ -310,16 +337,18 @@
                 lastStartIndex = 1 + totalResults - (totalResults % 
maxResults);
             }
             lastEndIndex = totalResults;
-            
+
             // Calculate next page
             if (currentStartIndex + maxResults > lastStartIndex) {
                 nextStartIndex = lastStartIndex;
-            } else {
+            }
+            else {
                 nextStartIndex = currentStartIndex + maxResults;
             }
             if (nextStartIndex + maxResults > lastEndIndex) {
                 nextEndIndex = lastEndIndex;
-            } else {
+            }
+            else {
                 nextEndIndex = Math.min(nextStartIndex + maxResults, 
totalResults);
             }
         }

Reply via email to