You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2013/11/06 16:57:30 UTC

svn commit: r1539376 [2/4] - in /syncope/trunk: client/src/main/java/org/apache/syncope/client/ common/src/main/java/org/apache/syncope/common/report/ common/src/main/java/org/apache/syncope/common/services/ common/src/main/java/org/apache/syncope/comm...

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.html?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.html Wed Nov  6 15:57:28 2013
@@ -16,48 +16,30 @@ KIND, either express or implied.  See th
 specific language governing permissions and limitations
 under the License.
 -->
-<wicket:extend>
-  <div id="tabs">
-    <ul>
-      <li class="tabs-selected"><a href="#tabs-1"><span><wicket:message key="approvals"/></span></a></li>
-      <li><a href="#tabs-2"><span><wicket:message key="userRequests"/></span></a></li>
-    </ul>
-    <div id="tabs-1">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:extend>
+    <div id="tabs">
+      <ul>
+        <li class="tabs-selected"><a href="#tabs-1"><span><wicket:message key="approvals"/></span></a></li>
+      </ul>
+      <div id="tabs-1">
 
-      <div id="users-contain" class="ui-widget" style="width:inherit;">
-        <span wicket:id="approvalContainer">
-          <table class="ui-widget ui-widget-content table-hover"
-                 wicket:id="approvalTable"/>
-        </span>
-        <span style="float:right">
-          <form wicket:id="approvalPaginatorForm" style="display:inline">
-            <label><wicket:message key="displayRows"/></label>
-            <select class="text ui-widget-content ui-corner-all"
-                    wicket:id="rowsChooser"/>
-          </form>
-        </span>
-      </div>
-
-      <div wicket:id="editApprovalWin">[Show modal window for editing approval]</div>
-    </div>
+        <div id="users-contain" class="ui-widget" style="width:inherit;">
+          <span wicket:id="approvalContainer">
+            <table class="ui-widget ui-widget-content table-hover"
+                   wicket:id="approvalTable"/>
+          </span>
+          <span style="float:right">
+            <form wicket:id="paginatorForm" style="display:inline">
+              <label><wicket:message key="displayRows"/></label>
+              <select class="text ui-widget-content ui-corner-all"
+                      wicket:id="rowsChooser"/>
+            </form>
+          </span>
+        </div>
 
-    <div id="tabs-2">
-
-      <div id="users-contain" class="ui-widget" style="width:inherit;">
-        <span wicket:id="userRequestContainer">
-          <table class="ui-widget ui-widget-content table-hover"
-                 wicket:id="userRequestTable"/>
-        </span>
-        <span style="float:right">
-          <form wicket:id="userRequestPaginatorForm" style="display:inline">
-            <label><wicket:message key="displayRows"/></label>
-            <select class="text ui-widget-content ui-corner-all"
-                    wicket:id="rowsChooser"/>
-          </form>
-        </span>
+        <div wicket:id="editApprovalWin">[Show modal window for editing approval]</div>
       </div>
-
-      <div wicket:id="editUserRequestWin">[Show modal window for editing user request]</div>
     </div>
-  </div>
-</wicket:extend>
+  </wicket:extend>
+</html>

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.properties?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo.properties Wed Nov  6 15:57:28 2013
@@ -22,8 +22,7 @@ dueDate=Due date
 owner=Owner
 claim=Claim
 manage=Manage
-approvals=Approval
-userRequests=User requests
+approvals=Approvals
 delete=Delete
 type=Type
 username=User

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_it.properties?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_it.properties Wed Nov  6 15:57:28 2013
@@ -23,7 +23,6 @@ owner=Esecutore
 claim=Richiedi
 manage=Gestisci
 approvals=Approvazioni
-userRequests=Richieste utente
 delete=Rimuovi
 type=Tipo
 username=Utente

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_pt_BR.properties?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Todo_pt_BR.properties Wed Nov  6 15:57:28 2013
@@ -23,7 +23,6 @@ owner=Propriet\u00e1rio
 claim=Requerimento
 manage=Ger\u00eancia
 approvals=Aprova\u00e7\u00e3o
-userRequests=Requisi\u00e7\u00f5es  de usu\u00e1rio
 delete=Excluir
 type=Tipo
 username=Usu\u00e1rio

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/WelcomePage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/WelcomePage.html?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/WelcomePage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/WelcomePage.html Wed Nov  6 15:57:28 2013
@@ -41,16 +41,16 @@ under the License.
     <div id="splash">
       <img src="img/logo.png" alt="syncope" title="syncope" id="logo" />
       <div style="display: table-row;">
-        <div id="username" style="padding-right: 5px;cursor: pointer;display: table-cell;">          
-          <a href="#" wicket:id="editProfileLink" style="font-family: monospace;padding-left: 130px;">
+        <div id="username" style="display: table-cell; padding-left: 5px; cursor: pointer; width:100%;">          
+          <a href="#" wicket:id="editProfileLink" style="font-family: monospace;line-height: 20px;">
             <span style="color: #B9CFB3;"><wicket:message key="welcome"/>,
               <span wicket:id="username" style="color: #B9CFB3;text-decoration: underline;"/>
             </span>
           </a>
         </div>
-        <div>
+        <div style="display: table-cell; padding-right: 5px;">
           <div wicket:id="infoModal"/>
-          <a wicket:id="infoLink"><img src="img/info.png" alt="info" style="padding-right: 10px;"/></a>
+          <a wicket:id="infoLink"><img src="img/info.png" alt="info"/></a>
         </div>
       </div>
       <ul>

Modified: syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java (original)
+++ syncope/trunk/console/src/test/java/org/apache/syncope/console/ConfigurationTestITCase.java Wed Nov  6 15:57:28 2013
@@ -50,7 +50,7 @@ public class ConfigurationTestITCase ext
 
         selenium.waitForCondition("selenium.isElementPresent(\"//input[@name='key:textField']\");", "30000");
 
-        assertEquals("createRequest.allowed", selenium.getAttribute("//input[@name='key:textField']@value"));
+        assertEquals("notification.maxRetries", selenium.getAttribute("//input[@name='key:textField']@value"));
 
         selenium.click("css=a.w_close");
     }

Modified: syncope/trunk/console/src/test/java/org/apache/syncope/console/ReportTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/test/java/org/apache/syncope/console/ReportTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/console/src/test/java/org/apache/syncope/console/ReportTestITCase.java (original)
+++ syncope/trunk/console/src/test/java/org/apache/syncope/console/ReportTestITCase.java Wed Nov  6 15:57:28 2013
@@ -77,6 +77,5 @@ public class ReportTestITCase extends Ab
         selenium.click("//div[3]/div[2]/span/form/div[2]/div/span/ul/li[11]/a");
         selenium.click("//div[3]/div[2]/span/form/div[2]/div/span/ul/li[12]/a");
         selenium.click("//div[3]/div[2]/span/form/div[2]/div/span/ul/li[13]/a");
-        selenium.click("//div[3]/div[2]/span/form/div[2]/div/span/ul/li[14]/a");
     }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ContentUpgrader.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ContentUpgrader.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ContentUpgrader.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/init/ContentUpgrader.java Wed Nov  6 15:57:28 2013
@@ -37,14 +37,12 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.Policy;
 import org.apache.syncope.core.persistence.beans.SyncTask;
 import org.apache.syncope.core.persistence.beans.SyncopeConf;
-import org.apache.syncope.core.persistence.beans.UserRequest;
 import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.dao.NotificationDAO;
 import org.apache.syncope.core.persistence.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.dao.ResourceDAO;
 import org.apache.syncope.core.persistence.dao.TaskDAO;
-import org.apache.syncope.core.persistence.dao.UserRequestDAO;
 import org.apache.syncope.core.persistence.dao.impl.AbstractContentDealer;
 import org.apache.syncope.core.util.ConnIdBundleManager;
 import org.apache.syncope.core.util.XMLSerializer;
@@ -80,9 +78,6 @@ public class ContentUpgrader extends Abs
     @Autowired
     private TaskDAO taskDAO;
 
-    @Autowired
-    private UserRequestDAO userRequestDAO;
-
     private void upgradeActiviti() {
         JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
 
@@ -93,14 +88,14 @@ public class ContentUpgrader extends Abs
                     "org\\.apache.syncope\\.core\\.workflow\\.activiti\\.",
                     "org.apache.syncope.core.workflow.user.activiti.task.").
                     replaceAll("org\\.apache\\.syncope\\.client\\.to\\.",
-                    "org.apache.syncope.common.to").
+                            "org.apache.syncope.common.to").
                     replaceAll("org\\.apache\\.syncope\\.types\\.",
-                    "org.apache.syncope.common.types").
+                            "org.apache.syncope.common.types").
                     replaceAll("org/apache/syncope/types/",
-                    "org/apache/syncope/common/types/").
+                            "org/apache/syncope/common/types/").
                     getBytes();
             jdbcTemplate.update("UPDATE ACT_GE_BYTEARRAY SET BYTES_=? WHERE ID_=?",
-                    new Object[] {updated, row.get("ID_")});
+                    new Object[] { updated, row.get("ID_") });
         }
     }
 
@@ -135,8 +130,8 @@ public class ContentUpgrader extends Abs
                 String oldConf = (String) xmlConfiguration.get(connInstance);
                 connInstance.setConfiguration(
                         XMLSerializer.<HashSet<ConnConfProperty>>deserialize(
-                        oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.ConnConfProperty",
-                        ConnConfProperty.class.getName())));
+                                oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.ConnConfProperty",
+                                        ConnConfProperty.class.getName())));
             } catch (Exception e) {
                 LOG.error("While upgrading {}", connInstance, e);
             }
@@ -152,8 +147,8 @@ public class ContentUpgrader extends Abs
                 if (StringUtils.isNotBlank(oldConf)) {
                     resource.setConnInstanceConfiguration(
                             XMLSerializer.<HashSet<ConnConfProperty>>deserialize(
-                            oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.ConnConfProperty",
-                            ConnConfProperty.class.getName())));
+                                    oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.ConnConfProperty",
+                                            ConnConfProperty.class.getName())));
                 }
             } catch (Exception e) {
                 LOG.error("While upgrading {}", resource, e);
@@ -169,9 +164,9 @@ public class ContentUpgrader extends Abs
                 String oldConf = (String) specification.get(policy);
                 policy.setSpecification(
                         XMLSerializer.<AbstractPolicySpec>deserialize(
-                        oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.",
-                        "org.apache.syncope.common.types.").
-                        replaceAll("alternativeSearchAttrs", "uAltSearchSchemas")));
+                                oldConf.replaceAll("org\\.apache\\.syncope\\.types\\.",
+                                        "org.apache.syncope.common.types.").
+                                replaceAll("alternativeSearchAttrs", "uAltSearchSchemas")));
             } catch (Exception e) {
                 LOG.error("While upgrading {}", policy, e);
             }
@@ -189,15 +184,15 @@ public class ContentUpgrader extends Abs
                 if (oldAbout != null) {
                     notification.setAbout(
                             XMLSerializer.<NodeCond>deserialize(
-                            oldAbout.replaceAll("org\\.apache\\.syncope\\.client\\.search\\.",
-                            "org.apache.syncope.common.search.")));
+                                    oldAbout.replaceAll("org\\.apache\\.syncope\\.client\\.search\\.",
+                                            "org.apache.syncope.common.search.")));
                 }
                 String oldRecipients = (String) xmlRecipients.get(notification);
                 if (oldRecipients != null) {
                     notification.setRecipients(
                             XMLSerializer.<NodeCond>deserialize(
-                            oldRecipients.replaceAll("org\\.apache\\.syncope\\.client\\.search\\.",
-                            "org.apache.syncope.common.search.")));
+                                    oldRecipients.replaceAll("org\\.apache\\.syncope\\.client\\.search\\.",
+                                            "org.apache.syncope.common.search.")));
                 }
             } catch (Exception e) {
                 LOG.error("While upgrading {}", notification, e);
@@ -214,10 +209,10 @@ public class ContentUpgrader extends Abs
                 if (oldUserTemplate != null) {
                     task.setUserTemplate(
                             XMLSerializer.<UserTO>deserialize(
-                            oldUserTemplate.replaceAll("org\\.apache\\.syncope\\.client\\.to\\.",
-                            "org.apache.syncope.common.to.").
-                            replaceAll("propagationTOs",
-                            "propagationStatusTOs")));
+                                    oldUserTemplate.replaceAll("org\\.apache\\.syncope\\.client\\.to\\.",
+                                            "org.apache.syncope.common.to.").
+                                    replaceAll("propagationTOs",
+                                            "propagationStatusTOs")));
                 }
             } catch (Exception e) {
                 LOG.error("While upgrading {}", task, e);
@@ -233,28 +228,9 @@ public class ContentUpgrader extends Abs
         for (Map<String, Object> row : rcInstances) {
             String updated = ((String) row.get("serializedInstance")).
                     replaceAll("org\\.apache\\.syncope\\.client\\.report\\.",
-                    "org.apache.syncope.common.report.");
+                            "org.apache.syncope.common.report.");
             jdbcTemplate.update("UPDATE ReportletConfInstance SET serializedInstance=? WHERE id=?",
-                    new Object[] {updated, row.get("id")});
-        }
-    }
-
-    private void upgradeUserRequest() {
-        Field payload = ReflectionUtils.findField(UserRequest.class, "payload");
-        payload.setAccessible(true);
-        for (UserRequest request : userRequestDAO.findAll()) {
-            try {
-                String oldPayload = (String) payload.get(request);
-                if (oldPayload != null) {
-                    payload.set(request,
-                            oldPayload.replaceAll("org\\.apache\\.syncope\\.client\\.to\\.",
-                            "org.apache.syncope.common.to.").
-                            replaceAll("org\\.apache\\.syncope\\.client\\.mod\\.",
-                            "org.apache.syncope.common.mod."));
-                }
-            } catch (Exception e) {
-                LOG.error("While upgrading {}", request, e);
-            }
+                    new Object[] { updated, row.get("id") });
         }
     }
 
@@ -283,8 +259,6 @@ public class ContentUpgrader extends Abs
 
         upgradeReportletConf();
 
-        upgradeUserRequest();
-
         Connection conn = DataSourceUtils.getConnection(dataSource);
         try {
             createIndexes();

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java Wed Nov  6 15:57:28 2013
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.notification;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Date;
 import javax.mail.internet.MimeMessage;
 import org.apache.commons.lang3.StringUtils;
@@ -33,6 +31,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.TaskExec;
 import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.TaskDAO;
+import org.apache.syncope.core.util.ExceptionUtil;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -205,12 +204,8 @@ public class NotificationJob implements 
                     LOG.error("Could not send e-mail", e);
 
                     execution.setStatus(Status.NOT_SENT.name());
-                    StringWriter exceptionWriter = new StringWriter();
-                    exceptionWriter.write(e.getMessage() + "\n\n");
-                    e.printStackTrace(new PrintWriter(exceptionWriter));
-
                     if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
-                        execution.setMessage(exceptionWriter.toString());
+                        execution.setMessage(ExceptionUtil.getFullStackTrace(e));
                     }
 
                     auditManager.audit(Category.notification, NotificationSubCategory.send, Result.failure,

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java Wed Nov  6 15:57:28 2013
@@ -40,7 +40,7 @@ import org.apache.syncope.core.persisten
 
 @Entity
 @Table(uniqueConstraints =
-        @UniqueConstraint(columnNames = {"syncopeUser_id", "syncopeRole_id"}))
+        @UniqueConstraint(columnNames = { "syncopeUser_id", "syncopeRole_id" }))
 public class Membership extends AbstractAttributable {
 
     private static final long serialVersionUID = 5030106264797289469L;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/SyncopeRole.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/SyncopeRole.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/SyncopeRole.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/SyncopeRole.java Wed Nov  6 15:57:28 2013
@@ -63,7 +63,7 @@ import org.apache.syncope.core.persisten
 
 @Entity
 @Table(uniqueConstraints =
-        @UniqueConstraint(columnNames = {"name", "parent_id"}))
+        @UniqueConstraint(columnNames = { "name", "parent_id" }))
 @Cacheable
 @SyncopeRoleCheck
 public class SyncopeRole extends AbstractAttributable {
@@ -284,7 +284,7 @@ public class SyncopeRole extends Abstrac
         this.inheritTemplates = getBooleanAsInteger(inheritAttrTemplates);
     }
 
-    @SuppressWarnings({"unchecked", "rawtypes"})
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public <T extends AbstractAttrTemplate> List<T> getAttrTemplates(final Class<T> reference) {
         List<T> result = null;
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java Wed Nov  6 15:57:28 2013
@@ -491,8 +491,8 @@ public class SyncopeUser extends Abstrac
                 res = passwordHistory.subList(size >= passwordHistory.size()
                         ? 0
                         : passwordHistory.size() - size, passwordHistory.size()).contains(cipherAlgorithm == null
-                        ? password
-                        : PasswordEncoder.encode(password, cipherAlgorithm));
+                                ? password
+                                : PasswordEncoder.encode(password, cipherAlgorithm));
             } catch (Exception e) {
                 LOG.error("Error evaluating password history", e);
             }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/RoleDAO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/RoleDAO.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/RoleDAO.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/RoleDAO.java Wed Nov  6 15:57:28 2013
@@ -26,7 +26,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.membership.Membership;
 import org.apache.syncope.core.persistence.beans.role.RAttrValue;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
-import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 
 public interface RoleDAO extends AttributableDAO {
@@ -37,9 +36,9 @@ public interface RoleDAO extends Attribu
 
     SyncopeRole find(String name, Long parent);
 
-    List<SyncopeRole> findOwned(SyncopeUser owner);
+    List<SyncopeRole> findOwnedByUser(Long userId);
 
-    List<SyncopeRole> findOwned(SyncopeRole owner);
+    List<SyncopeRole> findOwnedByRole(Long roleId);
 
     List<SyncopeRole> findByEntitlement(final Entitlement entitlement);
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/RoleDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/RoleDAOImpl.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/RoleDAOImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/RoleDAOImpl.java Wed Nov  6 15:57:28 2013
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.dao.impl;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import javax.persistence.NoResultException;
 import javax.persistence.Query;
@@ -60,6 +61,7 @@ import org.apache.syncope.core.util.Attr
 import org.apache.syncope.core.util.EntitlementUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class RoleDAOImpl extends AbstractAttributableDAOImpl implements RoleDAO {
@@ -144,8 +146,14 @@ public class RoleDAOImpl extends Abstrac
         result.add(role);
     }
 
+    @Transactional(readOnly = true)
     @Override
-    public List<SyncopeRole> findOwned(final SyncopeUser owner) {
+    public List<SyncopeRole> findOwnedByUser(final Long userId) {
+        SyncopeUser owner = userDAO.find(userId);
+        if (owner == null) {
+            return Collections.emptyList();
+        }
+
         StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(SyncopeRole.class.getSimpleName()).
                 append(" e WHERE e.userOwner=:owner ");
         for (Long roleId : owner.getRoleIds()) {
@@ -163,8 +171,14 @@ public class RoleDAOImpl extends Abstrac
         return result;
     }
 
+    @Transactional(readOnly = true)
     @Override
-    public List<SyncopeRole> findOwned(final SyncopeRole owner) {
+    public List<SyncopeRole> findOwnedByRole(final Long roleId) {
+        SyncopeRole owner = find(roleId);
+        if (owner == null) {
+            return Collections.emptyList();
+        }
+
         StringBuilder queryString = new StringBuilder("SELECT e FROM ").append(SyncopeRole.class.getSimpleName()).
                 append(" e WHERE e.roleOwner=:owner ");
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java Wed Nov  6 15:57:28 2013
@@ -128,8 +128,8 @@ public class SyncopeUserValidator extend
             LOG.debug("Invalid username");
 
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage()))
-                    .addNode("username").addConstraintViolation();
+                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
+                    addNode("username").addConstraintViolation();
 
             return false;
         }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/PropagationByResource.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/PropagationByResource.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/PropagationByResource.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/PropagationByResource.java Wed Nov  6 15:57:28 2013
@@ -298,14 +298,25 @@ public class PropagationByResource imple
      * @param propByRes to be merged
      */
     public final void merge(final PropagationByResource propByRes) {
-        toBeCreated.addAll(propByRes.get(ResourceOperation.CREATE));
-        toBeUpdated.addAll(propByRes.get(ResourceOperation.UPDATE));
-        toBeDeleted.addAll(propByRes.get(ResourceOperation.DELETE));
-        oldAccountIds.putAll(propByRes.getOldAccountIds());
+        if (propByRes != null) {
+            toBeCreated.addAll(propByRes.get(ResourceOperation.CREATE));
+            toBeUpdated.addAll(propByRes.get(ResourceOperation.UPDATE));
+            toBeDeleted.addAll(propByRes.get(ResourceOperation.DELETE));
+            oldAccountIds.putAll(propByRes.getOldAccountIds());
+        }
+    }
+
+    /**
+     * Removes all of the operations.
+     */
+    public void clear() {
+        toBeCreated.clear();
+        toBeUpdated.clear();
+        toBeDeleted.clear();
     }
 
     /**
-     * whether no operations are present.
+     * Whether no operations are present.
      *
      * @return true if no operations (create / update / delete) and no old account ids are present
      */

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java Wed Nov  6 15:57:28 2013
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.propagation.impl;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -48,6 +46,7 @@ import org.apache.syncope.core.rest.data
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.util.ApplicationContextProvider;
 import org.apache.syncope.core.util.AttributableUtil;
+import org.apache.syncope.core.util.ExceptionUtil;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -62,7 +61,7 @@ import org.springframework.beans.factory
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.transaction.annotation.Transactional;
 
-@Transactional(rollbackFor = {Throwable.class})
+@Transactional(rollbackFor = { Throwable.class })
 public abstract class AbstractPropagationTaskExecutor implements PropagationTaskExecutor {
 
     /**
@@ -317,10 +316,7 @@ public abstract class AbstractPropagatio
                 taskExecutionMessage = e.getCause().getMessage();
                 failureReason = e.getMessage() + "\n\n Cause: " + e.getCause().getMessage().split("\n")[0];
             } else {
-                StringWriter exceptionWriter = new StringWriter();
-                exceptionWriter.write(e.getMessage() + "\n\n");
-                e.printStackTrace(new PrintWriter(exceptionWriter));
-                taskExecutionMessage = exceptionWriter.toString();
+                taskExecutionMessage = ExceptionUtil.getFullStackTrace(e);
                 if (e.getCause() == null) {
                     failureReason = e.getMessage();
                 } else {
@@ -451,7 +447,7 @@ public abstract class AbstractPropagatio
                     new ObjectClass(task.getObjectClassName()),
                     new Uid(accountId),
                     connector.getOperationOptions(AttributableUtil.getInstance(task.getSubjectType()).
-                    getMappingItems(task.getResource(), MappingPurpose.PROPAGATION)));
+                            getMappingItems(task.getResource(), MappingPurpose.PROPAGATION)));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java Wed Nov  6 15:57:28 2013
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.apache.syncope.common.mod.AttributeMod;
+import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.common.to.AttributeTO;
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.IntMappingType;
@@ -223,56 +224,62 @@ public class PropagationManager {
     /**
      * Performs update on each resource associated to the user.
      *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow.
+     * @param wfResult user to be propagated (and info associated), as per result from workflow
+     * @param noPropResourceNames external resources not to be considered for propagation
      * @return list of propagation tasks
      * @throws NotFoundException if user is not found
      * @throws UnauthorizedRoleException if caller doesn't own enough entitlements to administer the given user
      */
-    public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<Long, Boolean>> wfResult)
+    public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<UserMod, Boolean>> wfResult,
+            final Collection<String> noPropResourceNames)
             throws NotFoundException, UnauthorizedRoleException {
 
-        return getUserUpdateTaskIds(
-                wfResult, null, Collections.<String>emptySet(), Collections.<AttributeMod>emptySet(), null);
+        SyncopeUser user = userDataBinder.getUserFromId(wfResult.getResult().getKey().getId());
+        return getUpdateTaskIds(user,
+                wfResult.getResult().getKey().getPassword(),
+                wfResult.getResult().getValue(),
+                wfResult.getResult().getKey().getVirAttrsToRemove(),
+                wfResult.getResult().getKey().getVirAttrsToUpdate(),
+                wfResult.getPropByRes(),
+                noPropResourceNames);
     }
 
-    /**
-     * Performs update on each resource associated to the user.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param password to be updated
-     * @param vAttrsToBeRemoved virtual attributes to be removed
-     * @param vAttrsToBeUpdated virtual attributes to be added
-     * @return list of propagation tasks
-     * @throws NotFoundException if user is not found
-     * @throws UnauthorizedRoleException if caller doesn't own enough entitlements to administer the given user
-     */
-    public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<Long, Boolean>> wfResult,
-            final String password, final Set<String> vAttrsToBeRemoved, final Set<AttributeMod> vAttrsToBeUpdated)
-            throws NotFoundException, UnauthorizedRoleException {
+    public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<UserMod, Boolean>> wfResult) {
+        UserMod userMod = wfResult.getResult().getKey();
 
-        return getUserUpdateTaskIds(wfResult, password, vAttrsToBeRemoved, vAttrsToBeUpdated, null);
-    }
+        // Propagate password update only to requested resources
+        List<PropagationTask> tasks = new ArrayList<PropagationTask>();
+        if (userMod.getPwdPropRequest() == null) {
+            // a. no specific password propagation request: generate propagation tasks for any resource associated
+            tasks = getUserUpdateTaskIds(wfResult, null);
+        } else {
+            // b. generate the propagation task list in two phases: first the ones containing password,
+            // the the rest (with no password)
+            final PropagationByResource origPropByRes = new PropagationByResource();
+            origPropByRes.merge(wfResult.getPropByRes());
+
+            Set<String> pwdResourceNames = new HashSet<String>(userMod.getPwdPropRequest().getResourceNames());
+            Set<String> currentResourceNames = userDataBinder.getResourceNamesForUserId(userMod.getId());
+            pwdResourceNames.retainAll(currentResourceNames);
+            PropagationByResource pwdPropByRes = new PropagationByResource();
+            pwdPropByRes.addAll(ResourceOperation.UPDATE, pwdResourceNames);
+            if (!pwdPropByRes.isEmpty()) {
+                Set<String> toBeExcluded = new HashSet<String>(currentResourceNames);
+                toBeExcluded.addAll(userMod.getResourcesToAdd());
+                toBeExcluded.removeAll(pwdResourceNames);
+                tasks.addAll(getUserUpdateTaskIds(wfResult, toBeExcluded));
+            }
 
-    /**
-     * Performs update on each resource associated to the user.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param password to be updated
-     * @param vAttrsToBeRemoved virtual attributes to be removed
-     * @param vAttrsToBeUpdated virtual attributes to be added
-     * @param noPropResourceNames external resources not to be considered for propagation
-     * @return list of propagation tasks
-     * @throws NotFoundException if user is not found
-     * @throws UnauthorizedRoleException if caller doesn't own enough entitlements to administer the given user
-     */
-    public List<PropagationTask> getUserUpdateTaskIds(final WorkflowResult<Map.Entry<Long, Boolean>> wfResult,
-            final String password, final Set<String> vAttrsToBeRemoved, final Set<AttributeMod> vAttrsToBeUpdated,
-            final Collection<String> noPropResourceNames)
-            throws NotFoundException, UnauthorizedRoleException {
+            final PropagationByResource nonPwdPropByRes = new PropagationByResource();
+            nonPwdPropByRes.merge(origPropByRes);
+            nonPwdPropByRes.removeAll(pwdResourceNames);
+            nonPwdPropByRes.purge();
+            if (!nonPwdPropByRes.isEmpty()) {
+                tasks.addAll(getUserUpdateTaskIds(wfResult, pwdResourceNames));
+            }
+        }
 
-        SyncopeUser user = userDataBinder.getUserFromId(wfResult.getResult().getKey());
-        return getUpdateTaskIds(user, password, wfResult.getResult().getValue(),
-                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames);
+        return tasks;
     }
 
     /**

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/quartz/AbstractTaskJob.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/quartz/AbstractTaskJob.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/quartz/AbstractTaskJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/quartz/AbstractTaskJob.java Wed Nov  6 15:57:28 2013
@@ -18,14 +18,13 @@
  */
 package org.apache.syncope.core.quartz;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Date;
 
 import org.apache.syncope.core.persistence.beans.Task;
 import org.apache.syncope.core.persistence.beans.TaskExec;
 import org.apache.syncope.core.persistence.dao.TaskDAO;
 import org.apache.syncope.core.persistence.dao.TaskExecDAO;
+import org.apache.syncope.core.util.ExceptionUtil;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
@@ -111,11 +110,7 @@ public abstract class AbstractTaskJob im
         } catch (JobExecutionException e) {
             LOG.error("While executing task " + taskId, e);
 
-            StringWriter exceptionWriter = new StringWriter();
-            exceptionWriter.write(e.getMessage() + "\n\n");
-            e.printStackTrace(new PrintWriter(exceptionWriter));
-            execution.setMessage(exceptionWriter.toString());
-
+            execution.setMessage(ExceptionUtil.getFullStackTrace(e));
             execution.setStatus(Status.FAILURE.name());
         }
         execution.setEndDate(new Date());

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/report/ReportJob.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/report/ReportJob.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/report/ReportJob.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/report/ReportJob.java Wed Nov  6 15:57:28 2013
@@ -20,7 +20,6 @@ package org.apache.syncope.core.report;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Date;
 import java.util.zip.Deflater;
@@ -31,6 +30,7 @@ import javax.xml.transform.Transformer;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.SyncopeConstants;
 import org.apache.syncope.common.report.ReportletConf;
 import org.apache.syncope.common.types.ReportExecStatus;
@@ -40,6 +40,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.ReportExecDAO;
 import org.apache.syncope.core.rest.data.ReportDataBinder;
 import org.apache.syncope.core.util.ApplicationContextProvider;
+import org.apache.syncope.core.util.ExceptionUtil;
 import org.quartz.DisallowConcurrentExecution;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
@@ -165,9 +166,9 @@ public class ReportJob implements Job {
                         Throwable t = e instanceof ReportException
                                 ? e.getCause()
                                 : e;
-                        exceptionWriter.write(t.getMessage() + "\n\n");
-                        t.printStackTrace(new PrintWriter(exceptionWriter));
-                        reportExecutionMessage.append(exceptionWriter.toString()).append("\n==================\n");
+                        reportExecutionMessage.
+                                append(ExceptionUtil.getFullStackTrace(t)).
+                                append("\n==================\n");
                     }
                 }
             }
@@ -181,17 +182,14 @@ public class ReportJob implements Job {
             }
         } catch (Exception e) {
             execution.setStatus(ReportExecStatus.FAILURE);
-
-            exceptionWriter.write(e.getMessage() + "\n\n");
-            e.printStackTrace(new PrintWriter(exceptionWriter));
-            reportExecutionMessage.append(exceptionWriter.toString());
+            reportExecutionMessage.append(ExceptionUtil.getFullStackTrace(e));
 
             throw new JobExecutionException(e, true);
         } finally {
             try {
                 zos.closeEntry();
-                zos.close();
-                baos.close();
+                IOUtils.closeQuietly(zos);
+                IOUtils.closeQuietly(baos);
             } catch (IOException e) {
                 LOG.error("While closing StreamResult's backend", e);
             }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/RoleController.java Wed Nov  6 15:57:28 2013
@@ -111,6 +111,10 @@ public class RoleController extends Abst
             role = binder.getRoleFromId(roleId);
         }
 
+        if (role == null) {
+            throw new NotFoundException("Role " + roleId);
+        }
+
         auditManager.audit(Category.role, RoleSubCategory.read, Result.success,
                 "Successfully read role: " + role.getId());
 
@@ -338,7 +342,7 @@ public class RoleController extends Abst
     public RoleTO delete(final Long roleId) {
         LOG.debug("Role delete called for {}", roleId);
 
-        List<SyncopeRole> ownedRoles = roleDAO.findOwned(binder.getRoleFromId(roleId));
+        List<SyncopeRole> ownedRoles = roleDAO.findOwnedByRole(roleId);
         if (!ownedRoles.isEmpty()) {
             List<String> owned = new ArrayList<String>(ownedRoles.size());
             for (SyncopeRole role : ownedRoles) {

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/SchemaController.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/SchemaController.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/SchemaController.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/SchemaController.java Wed Nov  6 15:57:28 2013
@@ -21,7 +21,6 @@ package org.apache.syncope.core.rest.con
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.EntityExistsException;
-import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.to.AbstractSchemaTO;
 import org.apache.syncope.common.to.DerSchemaTO;
@@ -31,7 +30,6 @@ import org.apache.syncope.common.types.A
 import org.apache.syncope.common.types.AuditElements;
 import org.apache.syncope.common.types.SchemaType;
 import org.apache.syncope.common.types.ClientExceptionType;
-import org.apache.syncope.common.validation.SyncopeClientCompositeException;
 import org.apache.syncope.common.validation.SyncopeClientException;
 import org.apache.syncope.core.audit.AuditManager;
 import org.apache.syncope.core.persistence.beans.AbstractDerSchema;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Wed Nov  6 15:57:28 2013
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.rest.controller;
 
+import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -35,21 +36,22 @@ import org.apache.syncope.common.to.Bulk
 import org.apache.syncope.common.to.MembershipTO;
 import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.common.types.AttributableType;
+import org.apache.syncope.common.types.AuditElements;
 import org.apache.syncope.common.types.AuditElements.Category;
 import org.apache.syncope.common.types.AuditElements.Result;
 import org.apache.syncope.common.types.AuditElements.UserSubCategory;
-import org.apache.syncope.common.types.ResourceOperation;
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.validation.SyncopeClientException;
 import org.apache.syncope.core.audit.AuditManager;
 import org.apache.syncope.core.notification.NotificationManager;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.SyncopeConf;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.AttributableSearchDAO;
+import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.RoleDAO;
 import org.apache.syncope.core.persistence.dao.UserDAO;
-import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.propagation.PropagationException;
 import org.apache.syncope.core.propagation.PropagationReporter;
 import org.apache.syncope.core.propagation.PropagationTaskExecutor;
@@ -95,6 +97,9 @@ public class UserController extends Abst
     protected AttributableSearchDAO searchDAO;
 
     @Autowired
+    protected ConfDAO confDAO;
+
+    @Autowired
     protected UserDataBinder binder;
 
     @Autowired
@@ -112,6 +117,15 @@ public class UserController extends Abst
     @Autowired
     protected NotificationManager notificationManager;
 
+    public boolean isSelfRegistrationAllowed() {
+        final SyncopeConf selfRegistrationAllowed = confDAO.find("selfRegistration.allowed", "false");
+
+        auditManager.audit(Category.user, AuditElements.UserSubCategory.selfRegistrationAllowed, Result.success,
+                "Successfully checked whether self registration is allowed");
+
+        return Boolean.valueOf(selfRegistrationAllowed.getValue());
+    }
+
     @PreAuthorize("hasRole('USER_READ')")
     public String getUsername(final Long userId) {
         return binder.getUserTO(userId).getUsername();
@@ -174,17 +188,6 @@ public class UserController extends Abst
         return userTOs;
     }
 
-    @PreAuthorize("hasRole('USER_READ')")
-    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
-    public UserTO read(final Long userId) {
-        UserTO result = binder.getUserTO(userId);
-
-        auditManager.audit(Category.user, UserSubCategory.read, Result.success,
-                "Successfully read user: " + userId);
-
-        return result;
-    }
-
     @PreAuthorize("isAuthenticated() "
             + "and not(hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
     @Transactional(readOnly = true)
@@ -199,6 +202,17 @@ public class UserController extends Abst
 
     @PreAuthorize("hasRole('USER_READ')")
     @Transactional(readOnly = true, rollbackFor = { Throwable.class })
+    public UserTO read(final Long userId) {
+        UserTO result = binder.getUserTO(userId);
+
+        auditManager.audit(Category.user, UserSubCategory.read, Result.success,
+                "Successfully read user: " + userId);
+
+        return result;
+    }
+
+    @PreAuthorize("hasRole('USER_READ')")
+    @Transactional(readOnly = true, rollbackFor = { Throwable.class })
     public List<UserTO> search(final NodeCond searchCondition)
             throws InvalidSearchConditionException {
 
@@ -232,6 +246,16 @@ public class UserController extends Abst
         return result;
     }
 
+    @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+    public UserTO createSelf(final UserTO userTO) {
+        if (!isSelfRegistrationAllowed()) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+            sce.getElements().add("SelfRegistration forbidden by configuration");
+        }
+
+        return doCreate(userTO);
+    }
+
     @PreAuthorize("hasRole('USER_CREATE')")
     public UserTO create(final UserTO userTO) {
         LOG.debug("User create called with {}", userTO);
@@ -246,6 +270,10 @@ public class UserController extends Abst
             throw new UnauthorizedRoleException(requestRoleIds);
         }
 
+        return doCreate(userTO);
+    }
+
+    protected UserTO doCreate(final UserTO userTO) {
         // Attributable transformation (if configured)
         UserTO actual = attrTransformer.transform(userTO);
         LOG.debug("Transformed: {}", actual);
@@ -279,70 +307,31 @@ public class UserController extends Abst
         return savedTO;
     }
 
+    @PreAuthorize("isAuthenticated() "
+            + "and not(hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+    public UserTO updateSelf(final UserMod userMod) {
+        UserTO userTO = binder.getAuthenticatedUserTO();
+
+        if (userTO.getId() != userMod.getId()) {
+            throw new AccessControlException("Not allowed for user id " + userMod.getId());
+        }
+
+        return update(userMod);
+    }
+
     @PreAuthorize("hasRole('USER_UPDATE')")
     public UserTO update(final UserMod userMod) {
         LOG.debug("User update called with {}", userMod);
 
-        final String changedPwd = userMod.getPassword();
-
         // AttributableMod transformation (if configured)
         UserMod actual = attrTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
+        /*
+         * Actual operations: workflow, propagation, notification
+         */
+        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(actual);
 
-        // 1. update password internally only if required
-        if (actual.getPwdPropRequest() != null && !actual.getPwdPropRequest().isOnSyncope()) {
-            actual.setPassword(null);
-        }
-        WorkflowResult<Map.Entry<Long, Boolean>> updated = uwfAdapter.update(actual);
-
-        // 2. propagate password update only to requested resources
-        List<PropagationTask> tasks = new ArrayList<PropagationTask>();
-        if (actual.getPwdPropRequest() == null) {
-            // 2a. no specific password propagation request: generate propagation tasks for any resource associated
-            tasks = propagationManager.getUserUpdateTaskIds(updated, changedPwd,
-                    actual.getVirAttrsToRemove(), actual.getVirAttrsToUpdate());
-        } else {
-            // 2b. generate the propagation task list in two phases: first the ones containing password,
-            // the the rest (with no password)
-            final PropagationByResource origPropByRes = new PropagationByResource();
-            origPropByRes.merge(updated.getPropByRes());
-
-            List<String> pwdResourceNames = actual.getPwdPropRequest().getResourceNames();
-            SyncopeUser user = binder.getUserFromId(updated.getResult().getKey());
-            pwdResourceNames.retainAll(user.getResourceNames());
-            final PropagationByResource pwdPropByRes = new PropagationByResource();
-            pwdPropByRes.addAll(ResourceOperation.UPDATE, pwdResourceNames);
-            updated.setPropByRes(pwdPropByRes);
-
-            if (!pwdPropByRes.isEmpty()) {
-                Set<String> toBeExcluded = new HashSet<String>(user.getResourceNames());
-                toBeExcluded.addAll(actual.getResourcesToAdd());
-                toBeExcluded.removeAll(pwdResourceNames);
-                tasks.addAll(propagationManager.getUserUpdateTaskIds(
-                        updated,
-                        changedPwd,
-                        actual.getVirAttrsToRemove(),
-                        actual.getVirAttrsToUpdate(),
-                        toBeExcluded));
-            }
-
-            final PropagationByResource nonPwdPropByRes = new PropagationByResource();
-            nonPwdPropByRes.merge(origPropByRes);
-            nonPwdPropByRes.removeAll(pwdResourceNames);
-            nonPwdPropByRes.purge();
-            updated.setPropByRes(nonPwdPropByRes);
-
-            if (!nonPwdPropByRes.isEmpty()) {
-                tasks.addAll(propagationManager.getUserUpdateTaskIds(
-                        updated,
-                        null,
-                        actual.getVirAttrsToRemove(),
-                        actual.getVirAttrsToUpdate(),
-                        pwdResourceNames));
-            }
-
-            updated.setPropByRes(origPropByRes);
-        }
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated);
 
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
                 getBean(PropagationReporter.class);
@@ -353,11 +342,9 @@ public class UserController extends Abst
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        // 3. create notification tasks
-        notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks());
+        notificationManager.createTasks(updated.getResult().getKey().getId(), updated.getPerformedTasks());
 
-        // 4. prepare result, including propagation status on external resources
-        final UserTO updatedTO = binder.getUserTO(updated.getResult().getKey());
+        final UserTO updatedTO = binder.getUserTO(updated.getResult().getKey().getId());
         updatedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
 
         auditManager.audit(Category.user, UserSubCategory.update, Result.success,
@@ -424,11 +411,19 @@ public class UserController extends Abst
         return savedTO;
     }
 
+    @PreAuthorize("isAuthenticated() "
+            + "and not(hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
+    public UserTO deleteSelf() {
+        UserTO userTO = binder.getAuthenticatedUserTO();
+
+        return delete(userTO.getId());
+    }
+
     @PreAuthorize("hasRole('USER_DELETE')")
     public UserTO delete(final Long userId) {
         LOG.debug("User delete called for {}", userId);
 
-        List<SyncopeRole> ownedRoles = roleDAO.findOwned(binder.getUserFromId(userId));
+        List<SyncopeRole> ownedRoles = roleDAO.findOwnedByUser(userId);
         if (!ownedRoles.isEmpty()) {
             List<String> owned = new ArrayList<String>(ownedRoles.size());
             for (SyncopeRole role : ownedRoles) {
@@ -452,9 +447,6 @@ public class UserController extends Abst
 
         List<PropagationTask> tasks = propagationManager.getUserDeleteTaskIds(userId);
 
-        final UserTO userTO = new UserTO();
-        userTO.setId(userId);
-
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
                 getBean(PropagationReporter.class);
         try {
@@ -464,16 +456,24 @@ public class UserController extends Abst
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        userTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
-
         uwfAdapter.delete(userId);
 
+        final UserTO deletedTO;
+        SyncopeUser deleted = userDAO.find(userId);
+        if (deleted == null) {
+            deletedTO = new UserTO();
+            deletedTO.setId(userId);
+        } else {
+            deletedTO = binder.getUserTO(userId);
+        }
+        deletedTO.getPropagationStatusTOs().addAll(propagationReporter.getStatuses());
+
         auditManager.audit(Category.user, UserSubCategory.delete, Result.success,
                 "Successfully deleted user: " + userId);
 
         LOG.debug("User successfully deleted: {}", userId);
 
-        return userTO;
+        return deletedTO;
     }
 
     @PreAuthorize("(hasRole('USER_DELETE') and #bulkAction.operation == #bulkAction.operation.DELETE) or "
@@ -542,9 +542,9 @@ public class UserController extends Abst
 
         userMod.getResourcesToRemove().addAll(resources);
 
-        final WorkflowResult<Map.Entry<Long, Boolean>> updated = uwfAdapter.update(userMod);
+        WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
 
-        final UserTO updatedTO = binder.getUserTO(updated.getResult().getKey());
+        final UserTO updatedTO = binder.getUserTO(updated.getResult().getKey().getId());
 
         auditManager.audit(Category.user, UserSubCategory.update, Result.success,
                 "Successfully updated user: " + updatedTO.getUsername());

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserWorkflowController.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserWorkflowController.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserWorkflowController.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserWorkflowController.java Wed Nov  6 15:57:28 2013
@@ -21,6 +21,8 @@ package org.apache.syncope.core.rest.con
 import java.util.AbstractMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.syncope.common.mod.AbstractAttributableMod;
+import org.apache.syncope.common.mod.UserMod;
 import org.apache.syncope.common.to.UserTO;
 import org.apache.syncope.common.to.WorkflowFormTO;
 import org.apache.syncope.common.types.AuditElements;
@@ -61,7 +63,7 @@ public class UserWorkflowController exte
     protected UserDataBinder binder;
 
     @PreAuthorize("hasRole('WORKFLOW_FORM_CLAIM')")
-    @Transactional(rollbackFor = {Throwable.class})
+    @Transactional(rollbackFor = { Throwable.class })
     public WorkflowFormTO claimForm(final String taskId) {
         WorkflowFormTO result = uwfAdapter.claimForm(taskId,
                 SecurityContextHolder.getContext().getAuthentication().getName());
@@ -79,10 +81,13 @@ public class UserWorkflowController exte
 
         WorkflowResult<Long> updated = uwfAdapter.execute(userTO, taskId);
 
+        UserMod userMod = new UserMod();
+        userMod.setId(userTO.getId());
+
         List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
-                new WorkflowResult<Map.Entry<Long, Boolean>>(
-                new AbstractMap.SimpleEntry<Long, Boolean>(updated.getResult(), null),
-                updated.getPropByRes(), updated.getPerformedTasks()));
+                new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                        new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, null),
+                        updated.getPropByRes(), updated.getPerformedTasks()));
 
         taskExecutor.execute(tasks);
 
@@ -100,7 +105,7 @@ public class UserWorkflowController exte
     }
 
     @PreAuthorize("hasRole('WORKFLOW_FORM_READ') and hasRole('USER_READ')")
-    @Transactional(rollbackFor = {Throwable.class})
+    @Transactional(rollbackFor = { Throwable.class })
     public WorkflowFormTO getFormForUser(final Long userId) {
         SyncopeUser user = binder.getUserFromId(userId);
         WorkflowFormTO result = uwfAdapter.getForm(user.getWorkflowId());
@@ -113,7 +118,7 @@ public class UserWorkflowController exte
     }
 
     @PreAuthorize("hasRole('WORKFLOW_FORM_LIST')")
-    @Transactional(rollbackFor = {Throwable.class})
+    @Transactional(rollbackFor = { Throwable.class })
     public List<WorkflowFormTO> getForms() {
         List<WorkflowFormTO> forms = uwfAdapter.getForms();
 
@@ -125,7 +130,7 @@ public class UserWorkflowController exte
     }
 
     @PreAuthorize("hasRole('WORKFLOW_FORM_READ') and hasRole('USER_READ')")
-    @Transactional(rollbackFor = {Throwable.class})
+    @Transactional(rollbackFor = { Throwable.class })
     public List<WorkflowFormTO> getForms(final Long userId, final String formName) {
         SyncopeUser user = binder.getUserFromId(userId);
         final List<WorkflowFormTO> result = uwfAdapter.getForms(user.getWorkflowId(), formName);
@@ -138,33 +143,32 @@ public class UserWorkflowController exte
     }
 
     @PreAuthorize("hasRole('WORKFLOW_FORM_SUBMIT')")
-    @Transactional(rollbackFor = {Throwable.class})
+    @Transactional(rollbackFor = { Throwable.class })
     public UserTO submitForm(final WorkflowFormTO form) {
         LOG.debug("About to process form {}", form);
 
-        WorkflowResult<Map.Entry<Long, String>> updated = uwfAdapter.submitForm(form,
-                SecurityContextHolder.getContext().getAuthentication().getName());
+        WorkflowResult<? extends AbstractAttributableMod> updated =
+                uwfAdapter.submitForm(form, SecurityContextHolder.getContext().getAuthentication().getName());
 
-        // propByRes can be made empty by the workflow definition is no propagation should occur 
+        // propByRes can be made empty by the workflow definition if no propagation should occur 
         // (for example, with rejected users)
-        if (updated.getPropByRes() != null && !updated.getPropByRes().isEmpty()) {
+        if (updated.getResult() instanceof UserMod
+                && updated.getPropByRes() != null && !updated.getPropByRes().isEmpty()) {
+
             List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
-                    new WorkflowResult<Map.Entry<Long, Boolean>>(
-                    new AbstractMap.SimpleEntry<Long, Boolean>(updated.getResult().getKey(), Boolean.TRUE),
-                    updated.getPropByRes(),
-                    updated.getPerformedTasks()),
-                    updated.getResult().getValue(),
-                    null,
-                    null,
-                    null);
+                    new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                            new AbstractMap.SimpleEntry<UserMod, Boolean>((UserMod) updated.getResult(), Boolean.TRUE),
+                            updated.getPropByRes(),
+                            updated.getPerformedTasks()));
+
             taskExecutor.execute(tasks);
         }
 
-        final UserTO savedTO = binder.getUserTO(updated.getResult().getKey());
+        UserTO savedTO = binder.getUserTO(updated.getResult().getId());
 
         auditManager.audit(AuditElements.Category.user, AuditElements.UserSubCategory.submitForm,
                 AuditElements.Result.success,
-                "Successfully submitted workflow form for user: " + savedTO.getUsername());
+                "Successfully submitted workflow form for : " + savedTO.getUsername());
 
         LOG.debug("About to return user after form processing\n{}", savedTO);
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Wed Nov  6 15:57:28 2013
@@ -88,7 +88,11 @@ public class UserDataBinder extends Abst
             throw new NotFoundException("User " + userId);
         }
 
-        if (!user.getUsername().equals(EntitlementUtil.getAuthenticatedUsername())) {
+        // Allows anonymous (during self-registration) and self (during self-update) to read own SyncopeUser,
+        // otherwise goes thorugh security checks to see if needed role entitlements are owned
+        if (!EntitlementUtil.getAuthenticatedUsername().equals(anonymousUser)
+                && !EntitlementUtil.getAuthenticatedUsername().equals(user.getUsername())) {
+
             Set<Long> roleIds = user.getRoleIds();
             Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
             roleIds.removeAll(adminRoleIds);
@@ -101,6 +105,11 @@ public class UserDataBinder extends Abst
     }
 
     @Transactional(readOnly = true)
+    public Set<String> getResourceNamesForUserId(final Long userId) {
+        return getUserFromId(userId).getResourceNames();
+    }
+
+    @Transactional(readOnly = true)
     public UserTO getAuthenticatedUserTO() {
         final UserTO authUserTO;
 
@@ -180,8 +189,8 @@ public class UserDataBinder extends Abst
         try {
             user.setPassword(password, getPredefinedCipherAlgoritm(), passwordHistorySize);
         } catch (NotFoundException e) {
-            final SyncopeClientException invalidCiperAlgorithm = SyncopeClientException.build(
-                    ClientExceptionType.NotFound);
+            final SyncopeClientException invalidCiperAlgorithm =
+                    SyncopeClientException.build(ClientExceptionType.NotFound);
             invalidCiperAlgorithm.getElements().add(e.getMessage());
             scce.addException(invalidCiperAlgorithm);
 
@@ -237,12 +246,15 @@ public class UserDataBinder extends Abst
     /**
      * Update user, given UserMod.
      *
-     * @param user to be updated
+     * @param toBeUpdated user to be updated
      * @param userMod bean containing update request
      * @return updated user + propagation by resource
      * @see PropagationByResource
      */
-    public PropagationByResource update(final SyncopeUser user, final UserMod userMod) {
+    public PropagationByResource update(final SyncopeUser toBeUpdated, final UserMod userMod) {
+        // Re-merge any pending change from workflow tasks
+        SyncopeUser user = userDAO.save(toBeUpdated);
+
         PropagationByResource propByRes = new PropagationByResource();
 
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java Wed Nov  6 15:57:28 2013
@@ -94,7 +94,7 @@ public class SyncopeAuthenticationProvid
     }
 
     @Override
-    @Transactional(noRollbackFor = {BadCredentialsException.class, DisabledException.class})
+    @Transactional(noRollbackFor = { BadCredentialsException.class, DisabledException.class })
     public Authentication authenticate(final Authentication authentication)
             throws AuthenticationException {
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeUserDetailsService.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeUserDetailsService.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeUserDetailsService.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeUserDetailsService.java Wed Nov  6 15:57:28 2013
@@ -84,7 +84,7 @@ public class SyncopeUserDetailsService i
                 }
             }
             // Give role operational entitlements for owned roles
-            List<SyncopeRole> ownedRoles = roleDAO.findOwned(user);
+            List<SyncopeRole> ownedRoles = roleDAO.findOwnedByUser(user.getId());
             if (!ownedRoles.isEmpty()) {
                 authorities.add(new SimpleGrantedAuthority("ROLE_CREATE"));
                 authorities.add(new SimpleGrantedAuthority("ROLE_READ"));

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java?rev=1539376&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java Wed Nov  6 15:57:28 2013
@@ -0,0 +1,75 @@
+/*
+ * 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.syncope.core.services;
+
+import java.net.URI;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.mod.UserMod;
+import org.apache.syncope.common.services.UserSelfService;
+import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.types.RESTHeaders;
+import org.apache.syncope.core.rest.controller.UserController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelfService, ContextAware {
+
+    @Autowired
+    private UserController controller;
+
+    @Override
+    public Response getOptions() {
+        return Response.ok().header("Allow", "GET,POST,OPTIONS,HEAD").
+                header(RESTHeaders.SELFREGISTRATION_ALLOWED.toString(), controller.isSelfRegistrationAllowed()).
+                build();
+    }
+
+    @Override
+    public Response create(final UserTO userTO) {
+        UserTO created = controller.createSelf(userTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getId())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID.toString(), created.getId()).
+                entity(created).
+                build();
+    }
+
+    @Override
+    public UserTO read() {
+        return controller.readSelf();
+    }
+
+    @Override
+    public Response update(final Long userId, final UserMod userMod) {
+        userMod.setId(userId);
+        UserTO updated = controller.updateSelf(userMod);
+        return Response.ok(updated).
+                build();
+
+    }
+
+    @Override
+    public Response delete() {
+        UserTO deleted = controller.deleteSelf();
+        return Response.ok(deleted).
+                build();
+    }
+
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserServiceImpl.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserServiceImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/services/UserServiceImpl.java Wed Nov  6 15:57:28 2013
@@ -93,12 +93,7 @@ public class UserServiceImpl extends Abs
     public UserTO read(final Long userId) {
         return controller.read(userId);
     }
-
-    @Override
-    public UserTO readSelf() {
-        return controller.readSelf();
-    }
-
+    
     @Override
     public List<UserTO> search(final NodeCond searchCondition) throws InvalidSearchConditionException {
         return controller.search(searchCondition);

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPMembershipSyncActions.java Wed Nov  6 15:57:28 2013
@@ -198,16 +198,14 @@ public class LDAPMembershipSyncActions e
         }
 
         try {
-            WorkflowResult<Map.Entry<Long, Boolean>> updated = uwfAdapter.update(userMod);
+            WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(userMod);
 
-            List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated,
-                    userMod.getPassword(), userMod.getVirAttrsToRemove(),
-                    userMod.getVirAttrsToUpdate(),
-                    Collections.singleton(resourceName));
+            List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+                    updated, Collections.singleton(resourceName));
 
             taskExecutor.execute(tasks);
 
-            notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks());
+            notificationManager.createTasks(updated.getResult().getKey().getId(), updated.getPerformedTasks());
         } catch (PropagationException e) {
             LOG.error("Could not propagate {}", userMod, e);
         } catch (Exception e) {

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java Wed Nov  6 15:57:28 2013
@@ -368,7 +368,6 @@ public class SyncopeSyncResultHandler im
             final ConnectorObject connObj, final List<String> altSearchSchemas, final AttributableUtil attrUtil) {
 
         // search for external attribute's name/value of each specified name
-
         final Map<String, Attribute> extValues = new HashMap<String, Attribute>();
 
         for (AbstractMappingItem item
@@ -467,7 +466,7 @@ public class SyncopeSyncResultHandler im
 
         final List<ConnectorObject> found = connector.search(objectClass,
                 new EqualsFilter(new Name(name)), connector.getOperationOptions(
-                attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)));
+                        attrUtil.getMappingItems(syncTask.getResource(), MappingPurpose.SYNCHRONIZATION)));
 
         if (found.isEmpty()) {
             LOG.debug("No {} found on {} with __NAME__ {}", objectClass, syncTask.getResource(), name);
@@ -605,7 +604,7 @@ public class SyncopeSyncResultHandler im
         UserMod actual = attrTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
 
-        WorkflowResult<Map.Entry<Long, Boolean>> updated;
+        WorkflowResult<Map.Entry<UserMod, Boolean>> updated;
         try {
             updated = uwfAdapter.update(actual);
         } catch (Exception e) {
@@ -614,8 +613,8 @@ public class SyncopeSyncResultHandler im
             result.setStatus(SyncResult.Status.FAILURE);
             result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
 
-            updated = new WorkflowResult<Map.Entry<Long, Boolean>>(
-                    new AbstractMap.SimpleEntry<Long, Boolean>(id, false), new PropagationByResource(),
+            updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
+                    new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false), new PropagationByResource(),
                     new HashSet<String>());
         }
 
@@ -641,17 +640,14 @@ public class SyncopeSyncResultHandler im
             }
         }
 
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated,
-                actual.getPassword(),
-                actual.getVirAttrsToRemove(),
-                actual.getVirAttrsToUpdate(),
-                Collections.singleton(syncTask.getResource().getName()));
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
+                updated, Collections.singleton(syncTask.getResource().getName()));
 
         taskExecutor.execute(tasks);
 
-        notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks());
+        notificationManager.createTasks(updated.getResult().getKey().getId(), updated.getPerformedTasks());
 
-        userTO = userDataBinder.getUserTO(updated.getResult().getKey());
+        userTO = userDataBinder.getUserTO(updated.getResult().getKey().getId());
 
         actions.after(this, delta, userTO, result);
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java?rev=1539376&r1=1539375&r2=1539376&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java Wed Nov  6 15:57:28 2013
@@ -52,8 +52,6 @@ import org.apache.syncope.common.Syncope
 import org.apache.syncope.core.persistence.dao.impl.AbstractContentDealer;
 import org.apache.syncope.core.util.multiparent.MultiParentNode;
 import org.apache.syncope.core.util.multiparent.MultiParentNodeOp;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.security.crypto.codec.Hex;
 import org.springframework.stereotype.Component;
@@ -67,9 +65,11 @@ import org.xml.sax.helpers.AttributesImp
 public class ContentExporter extends AbstractContentDealer {
 
     protected final static Set<String> TABLE_PREFIXES_TO_BE_EXCLUDED =
-            new HashSet<String>(Arrays.asList(new String[] {"QRTZ_", "LOGGING", "REPORTEXEC", "TASKEXEC",
-        "SYNCOPEUSER", "UATTR", "UATTRVALUE", "UATTRUNIQUEVALUE", "UDERATTR", "UVIRATTR",
-        "MEMBERSHIP", "MATTR", "MATTRVALUE", "MATTRUNIQUEVALUE", "MDERATTR", "MVIRATTR", "USERREQUEST"}));
+            new HashSet<String>(Arrays.asList(new String[] {
+                "QRTZ_", "LOGGING", "REPORTEXEC", "TASKEXEC",
+                "SYNCOPEUSER", "UATTR", "UATTRVALUE", "UATTRUNIQUEVALUE", "UDERATTR", "UVIRATTR",
+                "MEMBERSHIP", "MATTR", "MATTRVALUE", "MATTRUNIQUEVALUE", "MDERATTR", "MVIRATTR"
+            }));
 
     protected static final Map<String, String> TABLES_TO_BE_FILTERED =
             Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
@@ -325,7 +325,7 @@ public class ContentExporter extends Abs
 
             final String schema = dbSchema;
 
-            rs = meta.getTables(null, schema, null, new String[] {"TABLE"});
+            rs = meta.getTables(null, schema, null, new String[] { "TABLE" });
 
             final Set<String> tableNames = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
 

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java?rev=1539376&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java Wed Nov  6 15:57:28 2013
@@ -0,0 +1,47 @@
+/*
+ * 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.syncope.core.util;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
+public final class ExceptionUtil {
+
+    /**
+     * Uses commons lang's ExceptionUtils to provide a representation of the full stack trace of the given throwable.
+     *
+     * @param t throwable to build stack trace from
+     * @return a string representation of full stack trace of the given throwable
+     */
+    public static String getFullStackTrace(final Throwable t) {
+        StringBuilder result = new StringBuilder();
+
+        for (Throwable throwable : ExceptionUtils.getThrowableList(t)) {
+            result.append(ExceptionUtils.getMessage(throwable)).append('\n').
+                    append(ExceptionUtils.getStackTrace(throwable)).append("\n\n");
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Private default constructor, for static-only classes.
+     */
+    private ExceptionUtil() {
+    }
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/ExceptionUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain