syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jbernha...@apache.org
Subject svn commit: r1416827 [2/5] - in /syncope/branches/cxf/core/src: main/java/org/apache/syncope/core/init/ main/java/org/apache/syncope/core/notification/ main/java/org/apache/syncope/core/persistence/dao/ main/java/org/apache/syncope/core/persistence/dao...
Date Tue, 04 Dec 2012 09:02:36 GMT
Added: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1416827&view=auto
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (added)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Tue Dec  4 09:02:21 2012
@@ -0,0 +1,669 @@
+/*
+ * 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.rest.controller;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.collections.keyvalue.DefaultMapEntry;
+import org.apache.syncope.NotFoundException;
+import org.apache.syncope.controller.ContextAware;
+import org.apache.syncope.controller.InvalidSearchConditionException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
+import org.apache.syncope.controller.UserService;
+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.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.persistence.dao.UserSearchDAO;
+import org.apache.syncope.core.propagation.PropagationHandler;
+import org.apache.syncope.core.propagation.PropagationManager;
+import org.apache.syncope.core.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.rest.data.UserDataBinder;
+import org.apache.syncope.core.util.ConnObjectUtil;
+import org.apache.syncope.core.util.EntitlementUtil;
+import org.apache.syncope.core.workflow.UserWorkflowAdapter;
+import org.apache.syncope.core.workflow.WorkflowResult;
+import org.apache.syncope.mod.UserMod;
+import org.apache.syncope.propagation.PropagationException;
+import org.apache.syncope.search.NodeCond;
+import org.apache.syncope.to.MembershipTO;
+import org.apache.syncope.to.PropagationTO;
+import org.apache.syncope.to.UserTO;
+import org.apache.syncope.to.WorkflowFormTO;
+import org.apache.syncope.types.AuditElements.Category;
+import org.apache.syncope.types.AuditElements.Result;
+import org.apache.syncope.types.AuditElements.UserSubCategory;
+import org.apache.syncope.types.PropagationTaskExecStatus;
+import org.apache.syncope.workflow.WorkflowException;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+
+/**
+ * Note that this controller does not extend AbstractController, hence does not
+ * provide any Spring's Transactional logic at class level.
+ *
+ * @see AbstractController
+ */
+@Service
+public class UserController implements UserService, ContextAware {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(UserController.class);
+
+    @Autowired
+    private AuditManager auditManager;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private UserSearchDAO searchDAO;
+
+    @Autowired
+    private UserDataBinder userDataBinder;
+
+    @Autowired
+    private UserWorkflowAdapter wfAdapter;
+
+    @Autowired
+    private PropagationManager propagationManager;
+
+    @Autowired
+    private PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    /**
+     * ConnectorObject util.
+     */
+    @Autowired
+    private ConnObjectUtil connObjectUtil;
+
+    private UriInfo uriInfo;
+
+    @Override
+    public Boolean verifyPassword(final String username, final String password) {
+
+        auditManager.audit(Category.user, UserSubCategory.create, Result.success, "Verified password for: "
+                + username);
+
+        boolean authenticated;
+        try {
+            authenticated = userDataBinder.verifyPassword(username, password);
+        } catch (Exception e) {
+            return Boolean.FALSE;
+        }
+
+        return Boolean.valueOf(authenticated);
+    }
+
+    @Override
+    public int count() {
+        Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
+
+        return userDAO.count(adminRoleIds);
+    }
+
+    @Override
+    public int searchCount(final NodeCond searchCondition) throws InvalidSearchConditionException {
+
+        if (!searchCondition.checkValidity()) {
+            LOG.error("Invalid search condition: {}", searchCondition);
+            throw new InvalidSearchConditionException();
+        }
+
+        Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
+
+        return searchDAO.count(adminRoleIds, searchCondition);
+    }
+
+    @Override
+    public List<UserTO> list() {
+        List<SyncopeUser> users = userDAO.findAll(EntitlementUtil.getRoleIds(EntitlementUtil
+                .getOwnedEntitlementNames()));
+
+        List<UserTO> userTOs = new ArrayList<UserTO>(users.size());
+
+        for (SyncopeUser user : users) {
+            userTOs.add(userDataBinder.getUserTO(user));
+        }
+
+        auditManager.audit(Category.user, UserSubCategory.list, Result.success,
+                "Successfully listed all users: " + userTOs.size());
+
+        return userTOs;
+    }
+
+    @Override
+    public List<UserTO> list(final int page, final int size) {
+
+        Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
+
+        List<SyncopeUser> users = userDAO.findAll(adminRoleIds, page, size);
+        List<UserTO> userTOs = new ArrayList<UserTO>(users.size());
+        for (SyncopeUser user : users) {
+            userTOs.add(userDataBinder.getUserTO(user));
+        }
+
+        auditManager.audit(Category.user, UserSubCategory.list, Result.success,
+                "Successfully listed all users (page=" + page + ", size=" + size + "): " + userTOs.size());
+
+        return userTOs;
+    }
+
+    @Override
+    public UserTO read(final Long userId) throws NotFoundException, UnauthorizedRoleException {
+
+        UserTO result = userDataBinder.getUserTO(userId);
+
+        auditManager.audit(Category.user, UserSubCategory.read, Result.success, "Successfully read user: "
+                + userId);
+
+        return result;
+    }
+
+    @Override
+    public UserTO read(final String username) throws NotFoundException, UnauthorizedRoleException {
+
+        UserTO result = userDataBinder.getUserTO(username);
+
+        auditManager.audit(Category.user, UserSubCategory.read, Result.success, "Successfully read user: "
+                + username);
+
+        return result;
+    }
+
+    @Override
+    public List<UserTO> search(final NodeCond searchCondition) throws InvalidSearchConditionException {
+
+        LOG.debug("User search called with condition {}", searchCondition);
+
+        if (!searchCondition.checkValidity()) {
+            LOG.error("Invalid search condition: {}", searchCondition);
+            throw new InvalidSearchConditionException();
+        }
+
+        List<SyncopeUser> matchingUsers = searchDAO.search(
+                EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames()), searchCondition);
+        List<UserTO> result = new ArrayList<UserTO>(matchingUsers.size());
+        for (SyncopeUser user : matchingUsers) {
+            result.add(userDataBinder.getUserTO(user));
+        }
+
+        auditManager.audit(Category.user, UserSubCategory.read, Result.success,
+                "Successfully searched for users: " + result.size());
+
+        return result;
+    }
+
+    @Override
+    public List<UserTO> search(final NodeCond searchCondition, final int page, final int size)
+            throws InvalidSearchConditionException {
+
+        LOG.debug("User search called with condition {}", searchCondition);
+
+        if (!searchCondition.checkValidity()) {
+            LOG.error("Invalid search condition: {}", searchCondition);
+            throw new InvalidSearchConditionException();
+        }
+
+        final List<SyncopeUser> matchingUsers = searchDAO.search(
+                EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames()), searchCondition,
+                page, size);
+
+        final List<UserTO> result = new ArrayList<UserTO>(matchingUsers.size());
+        for (SyncopeUser user : matchingUsers) {
+            result.add(userDataBinder.getUserTO(user));
+        }
+
+        auditManager.audit(Category.user, UserSubCategory.read, Result.success,
+                "Successfully searched for users (page=" + page + ", size=" + size + "): " + result.size());
+
+        return result;
+    }
+
+    @Override
+    public Response create(final UserTO userTO) throws PropagationException, UnauthorizedRoleException,
+            WorkflowException, NotFoundException {
+
+        LOG.debug("User create called with {}", userTO);
+
+        Set<Long> requestRoleIds = new HashSet<Long>(userTO.getMemberships().size());
+        for (MembershipTO membership : userTO.getMemberships()) {
+            requestRoleIds.add(membership.getRoleId());
+        }
+
+        Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
+        requestRoleIds.removeAll(adminRoleIds);
+        if (!requestRoleIds.isEmpty()) {
+            throw new UnauthorizedRoleException(requestRoleIds);
+        }
+
+        WorkflowResult<Map.Entry<Long, Boolean>> created = wfAdapter.create(userTO);
+
+        List<PropagationTask> tasks = propagationManager.getCreateTaskIds(created, userTO.getPassword(),
+                userTO.getVirtualAttributes());
+
+        //final List<PropagationTO> propagations = new ArrayList<PropagationTO>();
+
+        taskExecutor.execute(tasks, new PropagationHandler() {
+
+            @Override
+            public void handle(final String resourceName, final PropagationTaskExecStatus executionStatus,
+                    final ConnectorObject beforeObj, final ConnectorObject afterObj) {
+
+                final PropagationTO propagation = new PropagationTO();
+                propagation.setResourceName(resourceName);
+                propagation.setStatus(executionStatus);
+
+                if (beforeObj != null) {
+                    propagation.setBeforeObj(connObjectUtil.getConnObjectTO(beforeObj));
+                }
+
+                if (afterObj != null) {
+                    propagation.setAfterObj(connObjectUtil.getConnObjectTO(afterObj));
+                }
+
+               // propagations.add(propagation);
+            }
+        });
+
+        notificationManager.createTasks(created.getResult().getKey(), created.getPerformedTasks());
+
+        final UserTO savedTO = userDataBinder.getUserTO(created.getResult().getKey());
+        //savedTO.setPropagationTOs(propagations);
+
+        LOG.debug("About to return created user\n{}", savedTO);
+
+        auditManager.audit(Category.user, UserSubCategory.create, Result.success,
+                "Successfully created user: " + savedTO.getUsername());
+
+        URI response = uriInfo.getAbsolutePathBuilder().path(created.getResult().getKey().toString()).build();
+        return Response.created(response).build();
+    }
+
+    @Override
+    public UserTO update(final UserMod userMod) throws NotFoundException, PropagationException,
+            UnauthorizedRoleException, WorkflowException {
+
+        LOG.debug("User update called with {}", userMod);
+
+        WorkflowResult<Map.Entry<Long, Boolean>> updated = wfAdapter.update(userMod);
+
+        List<PropagationTask> tasks = propagationManager.getUpdateTaskIds(updated, userMod.getPassword(),
+                userMod.getVirtualAttributesToBeRemoved(), userMod.getVirtualAttributesToBeUpdated(), null);
+
+        final List<PropagationTO> propagations = new ArrayList<PropagationTO>();
+
+        taskExecutor.execute(tasks, new PropagationHandler() {
+
+            @Override
+            public void handle(final String resourceName, final PropagationTaskExecStatus executionStatus,
+                    final ConnectorObject before, final ConnectorObject after) {
+
+                final PropagationTO propagation = new PropagationTO();
+                propagation.setResourceName(resourceName);
+                propagation.setStatus(executionStatus);
+
+                if (before != null) {
+                    propagation.setBeforeObj(connObjectUtil.getConnObjectTO(before));
+                }
+
+                if (after != null) {
+                    propagation.setAfterObj(connObjectUtil.getConnObjectTO(after));
+                }
+
+                propagations.add(propagation);
+            }
+        });
+
+        notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks());
+
+        final UserTO updatedTO = userDataBinder.getUserTO(updated.getResult().getKey());
+        updatedTO.setPropagationTOs(propagations);
+
+        auditManager.audit(Category.user, UserSubCategory.update, Result.success,
+                "Successfully updated user: " + updatedTO.getUsername());
+
+        LOG.debug("About to return updated user\n{}", updatedTO);
+
+        return updatedTO;
+    }
+
+    @Override
+    public UserTO activate(final Long userId, final String token, final Set<String> resourceNames,
+            final Boolean performLocally, final Boolean performRemotely) throws WorkflowException,
+            NotFoundException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to activate " + userId);
+
+        SyncopeUser user = userDAO.find(userId);
+        if (user == null) {
+            throw new NotFoundException("User " + userId);
+        }
+
+        return setStatus(user, token, resourceNames, performLocally, performRemotely, true, "activate");
+    }
+
+    @Deprecated
+    public UserTO activate(final String username, final String token,
+            final Set<String> resourceNames, final Boolean performLocally, final Boolean performRemotely)
+            throws WorkflowException, NotFoundException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to activate " + username);
+
+        SyncopeUser user = userDAO.find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
+        }
+
+        return setStatus(user, token, resourceNames, performLocally, performRemotely, true, "activate");
+    }
+
+    @Deprecated
+    public UserTO suspend(final String username, final Set<String> resourceNames,
+            final Boolean performLocally, final Boolean performRemotely) throws NotFoundException,
+            WorkflowException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to suspend " + username);
+
+        SyncopeUser user = userDAO.find(username);
+
+        if (user == null) {
+            throw new NotFoundException("User " + username);
+        }
+
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, false, "suspend");
+    }
+
+    @Override
+    public UserTO suspend(final Long userId, final Set<String> resourceNames, final Boolean performLocally,
+            final Boolean performRemotely) throws NotFoundException, WorkflowException,
+            UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to suspend " + userId);
+
+        SyncopeUser user = userDAO.find(userId);
+        if (user == null) {
+            throw new NotFoundException("User " + userId);
+        }
+
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, false, "suspend");
+    }
+
+    @Deprecated
+    public UserTO reactivate(Long userId, final Set<String> resourceNames,
+            final Boolean performLocally,
+            final Boolean performRemotely)
+            throws NotFoundException, WorkflowException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to reactivate " + userId);
+
+        SyncopeUser user = userDAO.find(userId);
+        if (user == null) {
+            throw new NotFoundException("User " + userId);
+        }
+
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, true, "reactivate");
+    }
+
+    @Deprecated
+    public UserTO reactivate(String username,
+            final Set<String> resourceNames,
+            final Boolean performLocally,
+            final Boolean performRemotely)
+            throws NotFoundException, WorkflowException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to reactivate " + username);
+
+        SyncopeUser user = userDAO.find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
+        }
+
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, true, "reactivate");
+    }
+
+    @Override
+    public Response delete(final Long userId) throws NotFoundException, WorkflowException,
+            PropagationException, UnauthorizedRoleException {
+        LOG.debug("User delete called with {}", userId);
+
+        doDelete(userId);
+
+        return Response.ok().build();
+    }
+
+    @Deprecated
+    public UserTO delete(final String username) throws NotFoundException, WorkflowException,
+            PropagationException, UnauthorizedRoleException {
+        LOG.debug("User delete called with {}", username);
+
+        UserTO result = userDataBinder.getUserTO(username);
+        long userId = result.getId();
+
+        doDelete(userId);
+
+        UserTO response = new UserTO();
+        response.setId(userId);
+        return response;
+    }
+
+    @Override
+    public UserTO executeWorkflow(final String taskId, final UserTO userTO) throws WorkflowException,
+            NotFoundException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to execute {} on {}", taskId, userTO.getId());
+
+        WorkflowResult<Long> updated = wfAdapter.execute(userTO, taskId);
+
+        List<PropagationTask> tasks = propagationManager
+                .getUpdateTaskIds(new WorkflowResult<Map.Entry<Long, Boolean>>(new DefaultMapEntry(updated
+                        .getResult(), null), updated.getPropByRes(), updated.getPerformedTasks()));
+
+        taskExecutor.execute(tasks);
+
+        notificationManager.createTasks(updated.getResult(), updated.getPerformedTasks());
+
+        final UserTO savedTO = userDataBinder.getUserTO(updated.getResult());
+
+        LOG.debug("About to return updated user\n{}", savedTO);
+
+        auditManager.audit(Category.user, UserSubCategory.executeWorkflow, Result.success,
+                "Successfully executed workflow action " + taskId + " on user: " + userTO.getUsername());
+
+        return savedTO;
+    }
+
+    @Override
+    public List<WorkflowFormTO> getForms() {
+        List<WorkflowFormTO> forms = wfAdapter.getForms();
+
+        auditManager.audit(Category.user, UserSubCategory.getForms, Result.success,
+                "Successfully list workflow forms: " + forms.size());
+
+        return forms;
+    }
+
+    @Override
+    public WorkflowFormTO getFormForUser(final Long userId) throws UnauthorizedRoleException,
+            NotFoundException, WorkflowException {
+
+        SyncopeUser user = userDataBinder.getUserFromId(userId);
+        WorkflowFormTO result = wfAdapter.getForm(user.getWorkflowId());
+
+        auditManager.audit(Category.user, UserSubCategory.getFormForUser, Result.success,
+                "Successfully read workflow form for user: " + user.getUsername());
+
+        return result;
+    }
+
+    @Override
+    public WorkflowFormTO claimForm(final String taskId) throws NotFoundException, WorkflowException {
+
+        WorkflowFormTO result = wfAdapter.claimForm(taskId, SecurityContextHolder.getContext()
+                .getAuthentication().getName());
+
+        auditManager.audit(Category.user, UserSubCategory.claimForm, Result.success,
+                "Successfully claimed workflow form: " + taskId);
+
+        return result;
+    }
+
+    @Override
+    public UserTO submitForm(final WorkflowFormTO form) throws NotFoundException, WorkflowException,
+            PropagationException, UnauthorizedRoleException {
+
+        LOG.debug("About to process form {}", form);
+
+        WorkflowResult<Map.Entry<Long, String>> updated = wfAdapter.submitForm(form, SecurityContextHolder
+                .getContext().getAuthentication().getName());
+
+        List<PropagationTask> tasks = propagationManager.getUpdateTaskIds(
+                new WorkflowResult<Map.Entry<Long, Boolean>>(new DefaultMapEntry(
+                        updated.getResult().getKey(), Boolean.TRUE), updated.getPropByRes(), updated
+                        .getPerformedTasks()), updated.getResult().getValue(), null, null);
+        taskExecutor.execute(tasks);
+
+        final UserTO savedTO = userDataBinder.getUserTO(updated.getResult().getKey());
+
+        auditManager.audit(Category.user, UserSubCategory.submitForm, Result.success,
+                "Successfully submitted workflow form for user: " + savedTO.getUsername());
+
+        LOG.debug("About to return user after form processing\n{}", savedTO);
+
+        return savedTO;
+    }
+
+    private UserTO setStatus(final SyncopeUser user, final String token, final Set<String> resourceNames,
+            final boolean performLocally, final boolean performRemotely, final boolean status,
+            final String task) throws NotFoundException, WorkflowException, UnauthorizedRoleException,
+            PropagationException {
+
+        LOG.debug("About to set status of {}" + user);
+
+        WorkflowResult<Long> updated;
+        if (performLocally) {
+            if ("suspend".equals(task)) {
+                updated = wfAdapter.suspend(user.getId());
+            } else if ("reactivate".equals(task)) {
+                updated = wfAdapter.reactivate(user.getId());
+            } else {
+                updated = wfAdapter.activate(user.getId(), token);
+            }
+        } else {
+            updated = new WorkflowResult<Long>(user.getId(), null, task);
+        }
+
+        // Resources to exclude from propagation.
+        Set<String> resources = new HashSet<String>();
+        if (performRemotely) {
+            if (resourceNames != null) {
+                resources.addAll(user.getResourceNames());
+                resources.removeAll(resourceNames);
+            }
+        } else {
+            resources.addAll(user.getResourceNames());
+        }
+
+        List<PropagationTask> tasks = propagationManager.getUpdateTaskIds(user, status, resources);
+
+        taskExecutor.execute(tasks);
+        notificationManager.createTasks(updated.getResult(), updated.getPerformedTasks());
+
+        final UserTO savedTO = userDataBinder.getUserTO(updated.getResult());
+
+        auditManager.audit(
+                Category.user,
+                UserSubCategory.setStatus,
+                Result.success,
+                "Successfully changed status to " + savedTO.getStatus() + " for user: "
+                        + savedTO.getUsername());
+
+        LOG.debug("About to return updated user\n{}", savedTO);
+
+        return savedTO;
+    }
+
+    protected void doDelete(final Long userId) throws NotFoundException, WorkflowException,
+            PropagationException, UnauthorizedRoleException {
+        // Note here that we can only notify about "delete", not any other
+        // task defined in workflow process definition: this because this
+        // information could only be available after wfAdapter.delete(), which
+        // will also effectively remove user from db, thus making virtually
+        // impossible by NotificationManager to fetch required user information
+        notificationManager.createTasks(userId, Collections.singleton("delete"));
+
+        List<PropagationTask> tasks = propagationManager.getDeleteTaskIds(userId);
+
+        //final UserTO userTO = new UserTO();
+        //userTO.setId(userId);
+
+        taskExecutor.execute(tasks, new PropagationHandler() {
+
+            @Override
+            public void handle(final String resourceName, final PropagationTaskExecStatus executionStatus,
+                    final ConnectorObject before, final ConnectorObject after) {
+
+                final PropagationTO propagation = new PropagationTO();
+                propagation.setResourceName(resourceName);
+                propagation.setStatus(executionStatus);
+
+                if (before != null) {
+                    propagation.setBeforeObj(connObjectUtil.getConnObjectTO(before));
+                }
+
+                if (after != null) {
+                    propagation.setAfterObj(connObjectUtil.getConnObjectTO(after));
+                }
+
+                //userTO.addPropagationTO(propagation);
+            }
+        });
+
+        wfAdapter.delete(userId);
+
+        auditManager.audit(Category.user, UserSubCategory.delete, Result.success,
+                "Successfully deleted userId: " + userId);
+
+        LOG.debug("User successfully deleted: {}", userId);
+    }
+
+    @Override
+    public void setUriInfo(UriInfo ui) {
+        this.uriInfo = ui;
+    }
+}

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserRequestController.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserRequestController.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserRequestController.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/UserRequestController.java Tue Dec  4 09:02:21 2012
@@ -21,13 +21,15 @@ package org.apache.syncope.core.rest.con
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.RollbackException;
+
+import org.apache.syncope.NotFoundException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.audit.AuditManager;
 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.UserRequestDAO;
 import org.apache.syncope.core.rest.data.UserRequestDataBinder;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserRequestTO;
 import org.apache.syncope.to.UserTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/VirtualSchemaController.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/VirtualSchemaController.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/VirtualSchemaController.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/VirtualSchemaController.java Tue Dec  4 09:02:21 2012
@@ -21,11 +21,12 @@ package org.apache.syncope.core.rest.con
 import java.util.ArrayList;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
+
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.audit.AuditManager;
 import org.apache.syncope.core.persistence.beans.AbstractVirSchema;
 import org.apache.syncope.core.persistence.dao.VirSchemaDAO;
 import org.apache.syncope.core.rest.data.VirtualSchemaDataBinder;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.to.VirtualSchemaTO;
 import org.apache.syncope.types.AuditElements.Category;
 import org.apache.syncope.types.AuditElements.Result;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/WorkflowController.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/WorkflowController.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/WorkflowController.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/controller/WorkflowController.java Tue Dec  4 09:02:21 2012
@@ -19,8 +19,9 @@
 package org.apache.syncope.core.rest.controller;
 
 import java.util.List;
+
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.audit.AuditManager;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.core.workflow.UserWorkflowAdapter;
 import org.apache.syncope.workflow.WorkflowException;
 import org.apache.syncope.to.WorkflowDefinitionTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ConnInstanceDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ConnInstanceDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ConnInstanceDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ConnInstanceDataBinder.java Tue Dec  4 09:02:21 2012
@@ -19,10 +19,11 @@
 package org.apache.syncope.core.rest.data;
 
 import java.util.Map;
+
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.persistence.beans.ConnInstance;
 import org.apache.syncope.core.persistence.dao.ConnInstanceDAO;
 import org.apache.syncope.core.util.ConnBundleManager;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.to.ConnInstanceTO;
 import org.apache.syncope.types.ConnConfPropSchema;
 import org.apache.syncope.types.ConnConfProperty;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/ResourceDataBinder.java Tue Dec  4 09:02:21 2012
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang.SerializationUtils;
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.persistence.beans.AccountPolicy;
 import org.apache.syncope.core.persistence.beans.ConnInstance;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
@@ -35,7 +36,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.ConnInstanceDAO;
 import org.apache.syncope.core.persistence.dao.PolicyDAO;
 import org.apache.syncope.core.util.JexlUtil;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.to.ResourceTO;
 import org.apache.syncope.to.SchemaMappingTO;
 import org.apache.syncope.types.ConnConfProperty;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/RoleDataBinder.java Tue Dec  4 09:02:21 2012
@@ -19,6 +19,8 @@
 package org.apache.syncope.core.rest.data;
 
 import java.util.List;
+
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.persistence.beans.AccountPolicy;
 import org.apache.syncope.core.persistence.beans.Entitlement;
 import org.apache.syncope.core.persistence.beans.PasswordPolicy;
@@ -30,7 +32,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.EntitlementDAO;
 import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.util.AttributableUtil;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.RoleMod;
 import org.apache.syncope.to.RoleTO;
 import org.apache.syncope.types.AttributableType;
@@ -105,7 +106,7 @@ public class RoleDataBinder extends Abst
 
         // entitlements
         Entitlement entitlement;
-        for (String entitlementName : roleTO.getEntitlements()) {
+        for (String entitlementName : roleTO.getEntitlementList()) {
             entitlement = entitlementDAO.find(entitlementName);
             if (entitlement == null) {
                 LOG.warn("Ignoring invalid entitlement {}", entitlementName);
@@ -185,9 +186,8 @@ public class RoleDataBinder extends Abst
         }
 
         // entitlements
-        if (roleMod.getEntitlements() != null) {
-            role.getEntitlements().clear();
-            for (String entitlementName : roleMod.getEntitlements()) {
+        if (roleMod.getEntitlementsToBeAdded().size() > 0) {
+            for (String entitlementName : roleMod.getEntitlementsToBeAdded()) {
                 Entitlement entitlement = entitlementDAO.find(entitlementName);
                 if (entitlement == null) {
                     LOG.warn("Ignoring invalid entitlement {}", entitlementName);
@@ -196,6 +196,16 @@ public class RoleDataBinder extends Abst
                 }
             }
         }
+        if (roleMod.getEntitlementsToBeRemoved().size() > 0) {
+            for (String entitlementName : roleMod.getEntitlementsToBeRemoved()) {
+                Entitlement entitlement = entitlementDAO.find(entitlementName);
+                if (entitlement == null) {
+                    LOG.warn("Ignoring invalid entitlement {}", entitlementName);
+                } else {
+                    role.removeEntitlement(entitlement);
+                }
+            }
+        }
 
         // policies
         if (roleMod.getPasswordPolicy() != null) {

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/TaskDataBinder.java Tue Dec  4 09:02:21 2012
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.rest.data;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.init.JobInstanceLoader;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.NotificationTask;
@@ -30,7 +31,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.ResourceDAO;
 import org.apache.syncope.core.persistence.dao.TaskExecDAO;
 import org.apache.syncope.core.util.JexlUtil;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.core.util.TaskUtil;
 import org.apache.syncope.to.AbstractAttributableTO;
 import org.apache.syncope.to.AttributeTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Tue Dec  4 09:02:21 2012
@@ -23,6 +23,8 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.NotFoundException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.persistence.beans.AbstractAttr;
 import org.apache.syncope.core.persistence.beans.AbstractDerAttr;
 import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
@@ -36,12 +38,10 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.propagation.PropagationByResource;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.security.PasswordEncoder;
 import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.core.util.ConnObjectUtil;
 import org.apache.syncope.core.util.EntitlementUtil;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.MembershipMod;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.MembershipTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserRequestDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserRequestDataBinder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserRequestDataBinder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/rest/data/UserRequestDataBinder.java Tue Dec  4 09:02:21 2012
@@ -19,11 +19,12 @@
 package org.apache.syncope.core.rest.data;
 
 import javax.persistence.RollbackException;
+
+import org.apache.syncope.NotFoundException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.persistence.beans.UserRequest;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.UserDAO;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserRequestTO;
 import org.apache.syncope.to.UserTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/sync/SyncopeSyncResultHanlder.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/sync/SyncopeSyncResultHanlder.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/sync/SyncopeSyncResultHanlder.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/sync/SyncopeSyncResultHanlder.java Tue Dec  4 09:02:21 2012
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.notification.NotificationManager;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
 import org.apache.syncope.core.persistence.beans.SchemaMapping;
@@ -42,11 +43,10 @@ import org.apache.syncope.core.propagati
 import org.apache.syncope.core.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.quartz.AbstractTaskJob;
 import org.apache.syncope.controller.InvalidSearchConditionException;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.util.ConnObjectUtil;
 import org.apache.syncope.core.util.EntitlementUtil;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.core.util.SchemaMappingUtil;
 import org.apache.syncope.core.workflow.UserWorkflowAdapter;
 import org.apache.syncope.core.workflow.WorkflowResult;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnBundleManager.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnBundleManager.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnBundleManager.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnBundleManager.java Tue Dec  4 09:02:21 2012
@@ -22,6 +22,8 @@ import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
+
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.core.persistence.beans.SyncopeConf;
 import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.MissingConfKeyException;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/util/ConnObjectUtil.java Tue Dec  4 09:02:21 2012
@@ -28,6 +28,8 @@ import java.util.Map;
 import java.util.Set;
 import org.apache.commons.lang.RandomStringUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.NotFoundException;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.init.ConnInstanceLoader;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
 import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
@@ -40,7 +42,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.ResourceDAO;
 import org.apache.syncope.core.persistence.dao.RoleDAO;
 import org.apache.syncope.core.propagation.ConnectorFacadeProxy;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.AbstractAttributableTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/AbstractUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/AbstractUserWorkflowAdapter.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/AbstractUserWorkflowAdapter.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/AbstractUserWorkflowAdapter.java Tue Dec  4 09:02:21 2012
@@ -18,15 +18,16 @@
  */
 package org.apache.syncope.core.workflow;
 
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.workflow.WorkflowException;
 import java.util.Map;
 import java.util.Map.Entry;
+
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.init.WorkflowLoader;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.UserDAO;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.rest.data.UserDataBinder;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserTO;
 import org.springframework.beans.factory.annotation.Autowired;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/ActivitiUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/ActivitiUserWorkflowAdapter.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/ActivitiUserWorkflowAdapter.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/ActivitiUserWorkflowAdapter.java Tue Dec  4 09:02:21 2012
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.workflow;
 
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.workflow.WorkflowException;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -55,12 +56,11 @@ import org.activiti.engine.runtime.Proce
 import org.activiti.engine.task.Task;
 import org.apache.commons.collections.keyvalue.DefaultMapEntry;
 import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.init.ActivitiWorkflowLoader;
 import org.apache.syncope.core.init.WorkflowLoader;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.propagation.PropagationByResource;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserTO;
 import org.apache.syncope.to.WorkflowDefinitionTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/NoOpUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/NoOpUserWorkflowAdapter.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/NoOpUserWorkflowAdapter.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/NoOpUserWorkflowAdapter.java Tue Dec  4 09:02:21 2012
@@ -18,16 +18,16 @@
  */
 package org.apache.syncope.core.workflow;
 
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.workflow.WorkflowException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections.keyvalue.DefaultMapEntry;
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.propagation.PropagationByResource;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserTO;
 import org.apache.syncope.to.WorkflowDefinitionTO;

Modified: syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/UserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/UserWorkflowAdapter.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/UserWorkflowAdapter.java (original)
+++ syncope/branches/cxf/core/src/main/java/org/apache/syncope/core/workflow/UserWorkflowAdapter.java Tue Dec  4 09:02:21 2012
@@ -18,14 +18,15 @@
  */
 package org.apache.syncope.core.workflow;
 
+import org.apache.syncope.NotFoundException;
 import org.apache.syncope.workflow.WorkflowException;
 import java.util.List;
 import java.util.Map;
+
+import org.apache.syncope.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.init.SpringContextInitializer;
 import org.apache.syncope.core.init.WorkflowLoader;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
-import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
-import org.apache.syncope.core.util.NotFoundException;
 import org.apache.syncope.mod.UserMod;
 import org.apache.syncope.to.UserTO;
 import org.apache.syncope.to.WorkflowDefinitionTO;

Modified: syncope/branches/cxf/core/src/main/resources/restContext.xml
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/resources/restContext.xml?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/resources/restContext.xml (original)
+++ syncope/branches/cxf/core/src/main/resources/restContext.xml Tue Dec  4 09:02:21 2012
@@ -1,100 +1,163 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:oxm="http://www.springframework.org/schema/oxm"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
+<!-- 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. -->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+   xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:util="http://www.springframework.org/schema/util"
+   xsi:schemaLocation="http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans.xsd
-       http://www.springframework.org/schema/context
+       http://www.springframework.org/schema/context                
        http://www.springframework.org/schema/context/spring-context.xsd
-       http://www.springframework.org/schema/oxm
-       http://www.springframework.org/schema/oxm/spring-oxm.xsd">
+       http://cxf.apache.org/jaxrs                                  
+       http://cxf.apache.org/schemas/jaxrs.xsd
+       http://www.springframework.org/schema/util 
+       http://www.springframework.org/schema/util/spring-util.xsd
+       http://www.springframework.org/schema/oxm                    
+       http://www.springframework.org/schema/oxm/spring-oxm.xsd"
+>
+
+   <import resource="classpath:META-INF/cxf/cxf.xml" />
+   <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
+
+   <context:component-scan base-package="org.apache.syncope.core.rest.controller" />
+
+   <bean id="depthProperties" class="org.apache.cxf.staxutils.DocumentDepthProperties">
+      <property name="innerElementCountThreshold" value="500" />
+   </bean>
+
+   <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
+      <property name="depthProperties" ref="depthProperties" />
+      <property name="marshallerProperties">
+         <map>
+            <entry key="jaxb.formatted.output">
+               <value type="java.lang.Boolean">true</value>
+            </entry>
+         </map>
+      </property>
+      <!--property name="collectionWrapperMap">
+         <map>
+            <entry>
+               <key>
+                  <value>com.foo.bar.MyObject</value>
+               </key>
+               <value>MyObjects</value>
+            </entry>
+         </map>
+      </property-->
+   </bean>
+
+   <util:list id="jsonKeys">
+      <value>roleTOs</value>
+   </util:list>
+
+   <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
+      <property name="depthProperties" ref="depthProperties" />
+      <property name="serializeAsArray" value="true" />
+      <property name="arrayKeys" ref="jsonKeys" />
+      <!-- Only for compartibility with Spring WS-Stack: -->
+      <property name="dropRootElement" value="true" />
+      <property name="supportUnwrapped" value="true" />
+   </bean>
+
+   <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
+      <entry key="http://www.example.org/books" value="b" />
+   </util:map>
+
+   <jaxrs:server id="restContainer" address="/">
+      <jaxrs:serviceBeans>
+         <ref bean="roleController" />
+         <ref bean="userController" />
+      </jaxrs:serviceBeans>
+      <jaxrs:resourceComparator>
+         <bean id="myServiceComparator" class="org.apache.syncope.core.rest.QueryResourceInfoComperator" />
+      </jaxrs:resourceComparator>
+      <jaxrs:providers>
+         <ref bean="jaxbProvider" />
+         <ref bean="jsonProvider" />
+         <bean class="org.apache.syncope.exceptions.RestHttpStatusCodeMapper" />
+      </jaxrs:providers>
+      <jaxrs:extensionMappings>
+         <entry key="json" value="application/json;charset=UTF-8" />
+         <entry key="xml" value="application/xml;charset=UTF-8" />
+      </jaxrs:extensionMappings>
+   </jaxrs:server>
+
+   <bean id="adminUser" class="java.lang.String">
+      <constructor-arg value="${adminUser}" />
+   </bean>
+
+   <!-- JSON (via Jackson) -->
+   <bean id="jacksonObjectMapper" class="org.apache.syncope.core.rest.data.UnwrappedObjectMapper" />
+   <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
+      <property name="objectMapper" ref="jacksonObjectMapper" />
+   </bean>
+
+   <!-- XML (via XStream) -->
+   <bean id="xStreamXmlMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
+      <property name="autodetectAnnotations" value="true" />
+   </bean>
+   <bean id="mappingXstreamHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
+      <constructor-arg ref="xStreamXmlMarshaller" />
+   </bean>
+
+   <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
+   <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
+      <property name="messageConverters">
+         <list>
+            <ref bean="mappingJacksonHttpMessageConverter" />
+            <ref bean="mappingXstreamHttpMessageConverter" />
+         </list>
+      </property>
+   </bean>
+
+   <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
+      <property name="mediaTypes">
+         <map>
+            <entry key="json" value="application/json;charset=UTF-8" />
+            <entry key="xml" value="application/xml;charset=UTF-8" />
+            <entry key="html" value="text/html;charset=UTF-8" />
+         </map>
+      </property>
+      <property name="viewResolvers">
+         <list>
+            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
+               <property name="prefix" value="/" />
+               <property name="suffix" value=".jsp" />
+            </bean>
+         </list>
+      </property>
+      <property name="defaultViews">
+         <list>
+            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
+               <property name="objectMapper" ref="jacksonObjectMapper" />
+            </bean>
+            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
+               <constructor-arg ref="xStreamXmlMarshaller" />
+            </bean>
+         </list>
+      </property>
+      <property name="defaultContentType">
+         <bean id="jsonMediaType" class="org.springframework.http.MediaType">
+            <constructor-arg value="application" />
+            <constructor-arg value="json" />
+            <constructor-arg value="UTF-8" />
+         </bean>
+      </property>
 
-  <context:component-scan base-package="org.apache.syncope.core.rest.controller"/>
-
-  <bean id="adminUser" class="java.lang.String">
-    <constructor-arg value="${adminUser}"/>
-  </bean>
-    
-    <!-- JSON (via Jackson) -->
-  <bean id="jacksonObjectMapper" class="org.apache.syncope.core.rest.data.UnwrappedObjectMapper"/>
-  <bean id="mappingJacksonHttpMessageConverter"
-          class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
-    <property name="objectMapper" ref="jacksonObjectMapper"/>
-  </bean>
-    
-    <!-- XML (via XStream) -->
-  <bean id="xStreamXmlMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
-    <property name="autodetectAnnotations" value="true" />
-  </bean> 
-  <bean id="mappingXstreamHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
-    <constructor-arg ref="xStreamXmlMarshaller" />
-  </bean>
-   
-  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
-  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
-    <property name="messageConverters">
-      <list>
-        <ref bean="mappingJacksonHttpMessageConverter"/>
-        <ref bean="mappingXstreamHttpMessageConverter" />
-      </list>
-    </property>
-  </bean>
-    
-  <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
-    <property name="mediaTypes">
-      <map>
-        <entry key="json" value="application/json;charset=UTF-8"/>
-        <entry key="xml" value="application/xml;charset=UTF-8"/>
-        <entry key="html" value="text/html;charset=UTF-8"/>
-      </map>
-    </property>
-    <property name="viewResolvers">
-      <list>
-        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
-          <property name="prefix" value="/"/>
-          <property name="suffix" value=".jsp"/>
-        </bean>
-      </list>
-    </property>
-    <property name="defaultViews">
-      <list>
-        <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
-          <property name="objectMapper" ref="jacksonObjectMapper"/>
-        </bean>
-        <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
-          <constructor-arg ref="xStreamXmlMarshaller"/>
-        </bean>
-      </list>
-    </property>
-    <property name="defaultContentType">        
-      <bean id="jsonMediaType" class="org.springframework.http.MediaType">
-        <constructor-arg value="application"/>
-        <constructor-arg value="json"/>
-        <constructor-arg value="UTF-8"/>
-      </bean>
-    </property>
-        
-    <property name="ignoreAcceptHeader" value="false"/>
-  </bean>
+      <property name="ignoreAcceptHeader" value="false" />
+   </bean>
 
 </beans>
\ No newline at end of file

Modified: syncope/branches/cxf/core/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/main/webapp/WEB-INF/web.xml?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/main/webapp/WEB-INF/web.xml (original)
+++ syncope/branches/cxf/core/src/main/webapp/WEB-INF/web.xml Tue Dec  4 09:02:21 2012
@@ -34,6 +34,20 @@ under the License.
   <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
+  
+  <servlet>
+    <servlet-name>CXFServlet</servlet-name>
+    <servlet-class>
+       org.apache.cxf.transport.servlet.CXFServlet
+    </servlet-class>
+    <load-on-startup>1</load-on-startup> 
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>CXFServlet</servlet-name>
+    <url-pattern>/cxf/*</url-pattern>
+  </servlet-mapping>
+  
 
   <servlet>
     <servlet-name>syncope-core-rest</servlet-name>

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/AbstractTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/AbstractTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/AbstractTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/AbstractTest.java Tue Dec  4 09:02:21 2012
@@ -48,7 +48,7 @@ public abstract class AbstractTest {
 
     protected static String bundlesDirectory;
 
-    private void logTableContent(final Connection conn, final String tableName) throws SQLException {
+    protected void logTableContent(final Connection conn, final String tableName) throws SQLException {
 
         LOG.debug("Table: " + tableName);
 

Added: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/notification/NotificationTests.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/notification/NotificationTests.java?rev=1416827&view=auto
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/notification/NotificationTests.java (added)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/notification/NotificationTests.java Tue Dec  4 09:02:21 2012
@@ -0,0 +1,359 @@
+/*
+ * 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.notification;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.annotation.Resource;
+import javax.mail.Flags.Flag;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Store;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.syncope.core.persistence.beans.Entitlement;
+import org.apache.syncope.core.persistence.beans.Notification;
+import org.apache.syncope.core.persistence.beans.NotificationTask;
+import org.apache.syncope.core.persistence.beans.SyncopeConf;
+import org.apache.syncope.core.persistence.dao.ConfDAO;
+import org.apache.syncope.core.persistence.dao.EntitlementDAO;
+import org.apache.syncope.core.persistence.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.dao.TaskDAO;
+import org.apache.syncope.core.rest.AbstractUserTestITCase;
+import org.apache.syncope.core.rest.controller.TaskController;
+import org.apache.syncope.core.rest.controller.UserController;
+import org.apache.syncope.search.MembershipCond;
+import org.apache.syncope.search.NodeCond;
+import org.apache.syncope.to.MembershipTO;
+import org.apache.syncope.to.NotificationTaskTO;
+import org.apache.syncope.to.UserTO;
+import org.apache.syncope.types.IntMappingType;
+import org.apache.syncope.types.TraceLevel;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.quartz.SchedulerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.TestingAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.icegreen.greenmail.util.GreenMail;
+import com.icegreen.greenmail.util.ServerSetup;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+    "classpath:syncopeContext.xml",
+    "classpath:restContext.xml",
+    "classpath:persistenceContext.xml",
+    "classpath:schedulingContext.xml",
+    "classpath:workflowContext.xml"
+})
+@Transactional
+public class NotificationTests {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(NotificationTests.class);
+
+    private static String smtpHost = "localhost";
+
+    private static int smtpPort = 2525;
+
+    private static String pop3Host = "localhost";
+
+    private static int pop3Port = 1110;
+
+    private static String mailAddress = "notificationtest@syncope.apache.org";
+
+    private static String mailPassword = "password";
+
+    private static GreenMail greenMail;
+
+    @Resource(name = "adminUser")
+    private String adminUser;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    @Autowired
+    private NotificationDAO notificationDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private ConfDAO confDAO;
+
+    @Autowired
+    private UserController userController;
+
+    @Autowired
+    private TaskController taskController;
+
+    @Autowired
+    private NotificationJob notificationJob;
+
+    @BeforeClass
+    public static void startGreenMail() {
+        ServerSetup[] config = new ServerSetup[2];
+        config[0] = new ServerSetup(smtpPort, smtpHost, ServerSetup.PROTOCOL_SMTP);
+        config[1] = new ServerSetup(pop3Port, pop3Host, ServerSetup.PROTOCOL_POP3);
+        greenMail = new GreenMail(config);
+        greenMail.setUser(mailAddress, mailPassword);
+        greenMail.start();
+    }
+
+    @AfterClass
+    public static void stopGreenMail() {
+        if (greenMail != null) {
+            greenMail.stop();
+        }
+    }
+
+    @Before
+    public void setupSecurity() {
+        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+        for (Entitlement entitlement : entitlementDAO.findAll()) {
+            authorities.add(new SimpleGrantedAuthority(entitlement.getName()));
+        }
+
+        UserDetails userDetails = new User(adminUser, "FAKE_PASSWORD", true, true, true, true, authorities);
+        Authentication authentication = new TestingAuthenticationToken(userDetails, "FAKE_PASSWORD", authorities);
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+    }
+
+    @Before
+    public void setupSMTP() {
+        try {
+            SyncopeConf smtpHostConf = confDAO.find("smtp.host");
+            smtpHostConf.setValue(smtpHost);
+            confDAO.save(smtpHostConf);
+
+            SyncopeConf smtpPortConf = confDAO.find("smtp.port");
+            smtpPortConf.setValue(Integer.toString(smtpPort));
+            confDAO.save(smtpPortConf);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while setting SMTP host and port");
+        }
+
+        confDAO.flush();
+    }
+
+    private boolean verifyMail(final String sender, final String subject) {
+        LOG.info("Waiting for notification to be sent...");
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+        }
+
+        boolean found = false;
+        try {
+            Session session = Session.getDefaultInstance(System.getProperties());
+            Store store = session.getStore("pop3");
+            store.connect(pop3Host, pop3Port, mailAddress, mailPassword);
+
+            Folder inbox = store.getFolder("INBOX");
+            assertNotNull(inbox);
+            inbox.open(Folder.READ_WRITE);
+
+            Message[] messages = inbox.getMessages();
+            for (Message message : messages) {
+                if (sender.equals(message.getFrom()[0].toString()) && subject.equals(message.getSubject())) {
+                    found = true;
+                    message.setFlag(Flag.DELETED, true);
+                }
+            }
+            inbox.close(true);
+            store.close();
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while fetching e-mail");
+        }
+
+        return found;
+    }
+
+    @Test
+    public void notifyByMail() {
+        // 1. create suitable notification for subsequent tests
+        Notification notification = new Notification();
+        notification.addEvent("create");
+
+        MembershipCond membCond = new MembershipCond();
+        membCond.setRoleId(7L);
+        notification.setAbout(NodeCond.getLeafCond(membCond));
+
+        membCond = new MembershipCond();
+        membCond.setRoleId(8L);
+        notification.setRecipients(NodeCond.getLeafCond(membCond));
+        notification.setSelfAsRecipient(true);
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+        Random random = new Random(System.currentTimeMillis());
+        String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
+        notification.setSender(sender);
+        String subject = "Test notification " + random.nextLong();
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+
+        notificationDAO.flush();
+
+        // 2. create user
+        UserTO userTO = AbstractUserTestITCase.getSampleTO(mailAddress);
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7);
+        userTO.addMembership(membershipTO);
+
+        try {
+            userController.create(userTO);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while creating");
+        }
+
+        // 3. force Quartz job execution and verify e-mail
+        try {
+            notificationJob.execute(null);
+        } catch (SchedulerException e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while triggering notification job");
+        }
+        assertTrue(verifyMail(sender, subject));
+
+        // 4. get NotificationTask id
+        Long taskId = null;
+        for (NotificationTask task : taskDAO.findAll(NotificationTask.class)) {
+            if (sender.equals(task.getSender())) {
+                taskId = task.getId();
+            }
+        }
+        assertNotNull(taskId);
+
+        // 5. execute Notification task and verify e-mail
+        try {
+            taskController.execute(taskId, false);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while executing notification task");
+        }
+        assertTrue(verifyMail(sender, subject));
+    }
+
+    @Test
+    public void issueSYNCOPE192() {
+        // 1. create suitable notification for subsequent tests
+        Notification notification = new Notification();
+        notification.addEvent("create");
+
+        MembershipCond membCond = new MembershipCond();
+        membCond.setRoleId(7L);
+        notification.setAbout(NodeCond.getLeafCond(membCond));
+
+        membCond = new MembershipCond();
+        membCond.setRoleId(8L);
+        notification.setRecipients(NodeCond.getLeafCond(membCond));
+        notification.setSelfAsRecipient(true);
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+        Random random = new Random(System.currentTimeMillis());
+        String sender = "syncope192-" + random.nextLong() + "@syncope.apache.org";
+        notification.setSender(sender);
+        String subject = "Test notification " + random.nextLong();
+        notification.setSubject(subject);
+        notification.setTemplate("optin");
+        notification.setTraceLevel(TraceLevel.NONE);
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+
+        notificationDAO.flush();
+
+        // 2. create user
+        UserTO userTO = AbstractUserTestITCase.getSampleTO(mailAddress);
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7);
+        userTO.addMembership(membershipTO);
+
+        try {
+            userController.create(userTO);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while creating");
+        }
+
+        // 3. force Quartz job execution and verify e-mail
+        try {
+            notificationJob.execute(null);
+        } catch (SchedulerException e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while triggering notification job");
+        }
+        assertTrue(verifyMail(sender, subject));
+
+        // 4. get NotificationTask id
+        Long taskId = null;
+        for (NotificationTask task : taskDAO.findAll(NotificationTask.class)) {
+            if (sender.equals(task.getSender())) {
+                taskId = task.getId();
+            }
+        }
+        assertNotNull(taskId);
+
+        // 5. verify that last exec status was updated
+        NotificationTaskTO task = null;
+        try {
+            task = (NotificationTaskTO) taskController.read(taskId);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception", e);
+            fail("Unexpected exception while reading notification task");
+        }
+        assertNotNull(task);
+        assertTrue(task.getExecutions().isEmpty());
+        assertTrue(task.isExecuted());
+        assertTrue(StringUtils.isNotBlank(task.getLatestExecStatus()));
+    }
+}

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java Tue Dec  4 09:02:21 2012
@@ -23,7 +23,6 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.dao.AttrDAO;
 import static org.junit.Assert.*;
 
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import java.util.List;
 import javax.validation.ValidationException;
 import org.junit.Test;
@@ -37,6 +36,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.types.AttributableType;
 import org.apache.syncope.types.EntityViolationType;
+import org.apache.syncope.validation.InvalidEntityException;
 
 @Transactional
 public class AttrTest extends AbstractTest {

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java Tue Dec  4 09:02:21 2012
@@ -30,12 +30,12 @@ import java.util.Set;
 
 import org.apache.syncope.core.AbstractTest;
 import org.apache.syncope.core.persistence.beans.Notification;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.search.AttributeCond;
 import org.apache.syncope.search.MembershipCond;
 import org.apache.syncope.search.NodeCond;
 import org.apache.syncope.types.EntityViolationType;
 import org.apache.syncope.types.IntMappingType;
+import org.apache.syncope.validation.InvalidEntityException;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/PolicyTest.java Tue Dec  4 09:02:21 2012
@@ -29,10 +29,10 @@ import org.apache.syncope.core.AbstractT
 import org.apache.syncope.core.persistence.beans.PasswordPolicy;
 import org.apache.syncope.core.persistence.beans.Policy;
 import org.apache.syncope.core.persistence.beans.SyncPolicy;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.types.PolicyType;
 import org.apache.syncope.types.PasswordPolicySpec;
 import org.apache.syncope.types.SyncPolicySpec;
+import org.apache.syncope.validation.InvalidEntityException;
 
 @Transactional
 public class PolicyTest extends AbstractTest {

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/ResourceTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/ResourceTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/ResourceTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/ResourceTest.java Tue Dec  4 09:02:21 2012
@@ -27,10 +27,10 @@ import org.apache.syncope.core.AbstractT
 import org.apache.syncope.core.persistence.beans.ConnInstance;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.SchemaMapping;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.core.util.SchemaMappingUtil;
 import org.apache.syncope.types.AttributableType;
 import org.apache.syncope.types.IntMappingType;
+import org.apache.syncope.validation.InvalidEntityException;
 import org.connid.bundles.soap.WebServiceConnector;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java Tue Dec  4 09:02:21 2012
@@ -30,9 +30,9 @@ import org.apache.syncope.core.AbstractT
 import org.apache.syncope.core.persistence.beans.AbstractSchema;
 import org.apache.syncope.core.persistence.beans.role.RAttr;
 import org.apache.syncope.core.util.AttributableUtil;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.types.AttributableType;
 import org.apache.syncope.types.SchemaType;
+import org.apache.syncope.validation.InvalidEntityException;
 
 @Transactional
 public class SchemaTest extends AbstractTest {

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/TaskTest.java Tue Dec  4 09:02:21 2012
@@ -29,11 +29,11 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.SchedTask;
 import org.apache.syncope.core.persistence.beans.SyncTask;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.core.quartz.TestSyncActions;
 import org.apache.syncope.to.UserTO;
 import org.apache.syncope.types.PropagationMode;
 import org.apache.syncope.types.PropagationOperation;
+import org.apache.syncope.validation.InvalidEntityException;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.junit.Test;

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java Tue Dec  4 09:02:21 2012
@@ -26,12 +26,12 @@ import java.util.Set;
 import org.apache.syncope.core.AbstractTest;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.beans.user.UAttrValue;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.controller.InvalidSearchConditionException;
 import org.apache.syncope.core.util.EntitlementUtil;
 import org.apache.syncope.core.util.IncompatiblePolicyException;
 import org.apache.syncope.core.util.PasswordGenerator;
 import org.apache.syncope.types.CipherAlgorithm;
+import org.apache.syncope.validation.InvalidEntityException;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;

Modified: syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java?rev=1416827&r1=1416826&r2=1416827&view=diff
==============================================================================
--- syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java (original)
+++ syncope/branches/cxf/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java Tue Dec  4 09:02:21 2012
@@ -38,7 +38,7 @@ import org.apache.syncope.core.persisten
 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.PolicyDAO;
-import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
+import org.apache.syncope.validation.InvalidEntityException;
 
 @Transactional
 public class RoleTest extends AbstractTest {



Mime
View raw message