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 2015/01/12 18:41:07 UTC

[4/7] syncope git commit: [SYNCOPE-620] server-rest-cxf

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConnectorServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConnectorServiceImpl.java
new file mode 100644
index 0000000..369c8c1
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ConnectorServiceImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.server.logic.ConnectorLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ConnectorServiceImpl extends AbstractServiceImpl implements ConnectorService {
+
+    @Autowired
+    private ConnectorLogic logic;
+
+    @Override
+    public Response create(final ConnInstanceTO connInstanceTO) {
+        ConnInstanceTO connInstance = logic.create(connInstanceTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(connInstance.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, connInstance.getKey()).
+                build();
+    }
+
+    @Override
+    public void delete(final Long connInstanceKey) {
+        logic.delete(connInstanceKey);
+    }
+
+    @Override
+    public List<ConnBundleTO> getBundles(final String lang) {
+        return logic.getBundles(lang);
+    }
+
+    @Override
+    public List<ConnConfProperty> getConfigurationProperties(final Long connInstanceKey) {
+        return logic.getConfigurationProperties(connInstanceKey);
+    }
+
+    @Override
+    public List<PlainSchemaTO> getSchemaNames(final Long connInstanceKey, final ConnInstanceTO connInstanceTO,
+            final boolean includeSpecial) {
+
+        connInstanceTO.setKey(connInstanceKey);
+
+        List<String> schemaNames = logic.getSchemaNames(connInstanceTO, includeSpecial);
+        List<PlainSchemaTO> result = new ArrayList<>(schemaNames.size());
+        for (String name : schemaNames) {
+            PlainSchemaTO schemaTO = new PlainSchemaTO();
+            schemaTO.setKey(name);
+            result.add(schemaTO);
+        }
+        return result;
+    }
+
+    @Override
+    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long connInstanceKey,
+            final ConnInstanceTO connInstanceTO) {
+
+        connInstanceTO.setKey(connInstanceKey);
+
+        List<String> objectClasses = logic.getSupportedObjectClasses(connInstanceTO);
+        List<ConnIdObjectClassTO> result = new ArrayList<>(objectClasses.size());
+        for (String objectClass : objectClasses) {
+            result.add(new ConnIdObjectClassTO(objectClass));
+        }
+        return result;
+    }
+
+    @Override
+    public List<ConnInstanceTO> list(final String lang) {
+        return logic.list(lang);
+    }
+
+    @Override
+    public ConnInstanceTO read(final Long connInstanceKey) {
+        return logic.read(connInstanceKey);
+    }
+
+    @Override
+    public ConnInstanceTO readByResource(final String resourceName) {
+        return logic.readByResource(resourceName);
+    }
+
+    @Override
+    public void update(final Long connInstanceKey, final ConnInstanceTO connInstanceTO) {
+        connInstanceTO.setKey(connInstanceKey);
+        logic.update(connInstanceTO);
+    }
+
+    @Override
+    public boolean check(final ConnInstanceTO connInstanceTO) {
+        return logic.check(connInstanceTO);
+    }
+
+    @Override
+    public void reload() {
+        logic.reload();
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        return logic.bulk(bulkAction);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/EntitlementServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/EntitlementServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/EntitlementServiceImpl.java
new file mode 100644
index 0000000..70e6114
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/EntitlementServiceImpl.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.util.List;
+import org.apache.syncope.common.lib.wrap.EntitlementTO;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.EntitlementService;
+import org.apache.syncope.server.logic.EntitlementLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EntitlementServiceImpl extends AbstractServiceImpl implements EntitlementService {
+
+    @Autowired
+    private EntitlementLogic logic;
+
+    @Override
+    public List<EntitlementTO> getAllEntitlements() {
+        return CollectionWrapper.wrap(logic.getAll(), EntitlementTO.class);
+    }
+
+    @Override
+    public List<EntitlementTO> getOwnEntitlements() {
+        return CollectionWrapper.wrap(logic.getOwn(), EntitlementTO.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
new file mode 100644
index 0000000..09995b1
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
@@ -0,0 +1,114 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.text.ParseException;
+import java.util.List;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.LoggerService;
+import org.apache.syncope.server.logic.LoggerLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerService {
+
+    @Autowired
+    private LoggerLogic logic;
+
+    @Override
+    public void delete(final LoggerType type, final String name) {
+        switch (type) {
+            case LOG:
+                logic.deleteLog(name);
+                break;
+
+            case AUDIT:
+                try {
+                    logic.disableAudit(AuditLoggerName.fromLoggerName(name));
+                } catch (IllegalArgumentException e) {
+                    throw new BadRequestException(e);
+                } catch (ParseException e) {
+                    throw new BadRequestException(e);
+                }
+                break;
+
+            default:
+                throw new BadRequestException();
+        }
+
+    }
+
+    @Override
+    public List<LoggerTO> list(final LoggerType type) {
+        switch (type) {
+            case LOG:
+                return logic.listLogs();
+
+            case AUDIT:
+                List<AuditLoggerName> auditLogger = logic.listAudits();
+                return CollectionWrapper.unwrapLogger(auditLogger);
+
+            default:
+                throw new BadRequestException();
+        }
+    }
+
+    @Override
+    public LoggerTO read(final LoggerType type, final String name) {
+        List<LoggerTO> logger = list(type);
+        for (LoggerTO l : logger) {
+            if (l.getName().equals(name)) {
+                return l;
+            }
+        }
+        throw new NotFoundException();
+    }
+
+    @Override
+    public void update(final LoggerType type, final String name, final LoggerTO logger) {
+        switch (type) {
+            case LOG:
+                logic.setLogLevel(name, logger.getLevel().getLevel());
+                break;
+
+            case AUDIT:
+                try {
+                    logic.enableAudit(AuditLoggerName.fromLoggerName(name));
+                } catch (Exception e) {
+                    throw new BadRequestException(e);
+                }
+                break;
+
+            default:
+                throw new BadRequestException();
+        }
+    }
+
+    @Override
+    public List<EventCategoryTO> events() {
+        return logic.listAuditEvents();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/NotificationServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/NotificationServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/NotificationServiceImpl.java
new file mode 100644
index 0000000..a25ae9d
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/NotificationServiceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.server.logic.NotificationLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class NotificationServiceImpl extends AbstractServiceImpl implements NotificationService {
+
+    @Autowired
+    private NotificationLogic logic;
+
+    @Override
+    public Response create(final NotificationTO notificationTO) {
+        NotificationTO created = logic.create(notificationTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public NotificationTO read(final Long notificationKey) {
+        return logic.read(notificationKey);
+    }
+
+    @Override
+    public List<NotificationTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public void update(final Long notificationKey, final NotificationTO notificationTO) {
+        notificationTO.setKey(notificationKey);
+        logic.update(notificationTO);
+    }
+
+    @Override
+    public void delete(final Long notificationKey) {
+        logic.delete(notificationKey);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
new file mode 100644
index 0000000..da50761
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/PolicyServiceImpl.java
@@ -0,0 +1,125 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.wrap.CorrelationRuleClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.server.logic.PolicyLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyService {
+
+    @Autowired
+    private PolicyLogic logic;
+
+    @Override
+    public <T extends AbstractPolicyTO> Response create(final T policyTO) {
+        AbstractPolicyTO policy = logic.create(policyTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(policy.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID.toString(), policy.getKey()).
+                build();
+    }
+
+    @Override
+    public void delete(final Long policyKey) {
+        logic.delete(policyKey);
+    }
+
+    @Override
+    public <T extends AbstractPolicyTO> List<T> list(final PolicyType type) {
+        return logic.list(type);
+    }
+
+    @Override
+    public <T extends AbstractPolicyTO> T read(final Long policyKey) {
+        return logic.read(policyKey);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends AbstractPolicyTO> T readGlobal(final PolicyType type) {
+        T result = null;
+
+        switch (type) {
+            case ACCOUNT:
+            case GLOBAL_ACCOUNT:
+                result = (T) logic.getGlobalAccountPolicy();
+                break;
+
+            case PASSWORD:
+            case GLOBAL_PASSWORD:
+                result = (T) logic.getGlobalPasswordPolicy();
+                break;
+
+            case SYNC:
+            case GLOBAL_SYNC:
+                result = (T) logic.getGlobalSyncPolicy();
+                break;
+
+            default:
+                throw new BadRequestException();
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends AbstractPolicyTO> void update(final Long policyKey, final T policyTO) {
+        policyTO.setKey(policyKey);
+
+        switch (policyTO.getType()) {
+            case ACCOUNT:
+            case GLOBAL_ACCOUNT:
+                logic.update((AccountPolicyTO) policyTO);
+                break;
+
+            case PASSWORD:
+            case GLOBAL_PASSWORD:
+                logic.update((PasswordPolicyTO) policyTO);
+                break;
+
+            case SYNC:
+            case GLOBAL_SYNC:
+                logic.update((SyncPolicyTO) policyTO);
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    @Override
+    public List<CorrelationRuleClass> getSyncCorrelationRuleClasses() {
+        return CollectionWrapper.wrap(logic.getSyncCorrelationRuleClasses(), CorrelationRuleClass.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
new file mode 100644
index 0000000..3b30337
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
@@ -0,0 +1,131 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.lib.wrap.ReportletConfClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.server.logic.ReportLogic;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.entity.ReportExec;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ReportServiceImpl extends AbstractServiceImpl implements ReportService {
+
+    @Autowired
+    private ReportLogic logic;
+
+    @Override
+    public Response create(final ReportTO reportTO) {
+        ReportTO createdReportTO = logic.create(reportTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdReportTO.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID.toString(), createdReportTO.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final Long reportKey, final ReportTO reportTO) {
+        reportTO.setKey(reportKey);
+        logic.update(reportTO);
+    }
+
+    @Override
+    public PagedResult<ReportTO> list() {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public PagedResult<ReportTO> list(final String orderBy) {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public PagedResult<ReportTO> list(final Integer page, final Integer size) {
+        return list(page, size, null);
+    }
+
+    @Override
+    public PagedResult<ReportTO> list(final Integer page, final Integer size, final String orderBy) {
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return buildPagedResult(logic.list(page, size, orderByClauses), page, size, logic.count());
+    }
+
+    @Override
+    public List<ReportletConfClass> getReportletConfClasses() {
+        return CollectionWrapper.wrap(logic.getReportletConfClasses(), ReportletConfClass.class);
+    }
+
+    @Override
+    public ReportTO read(final Long reportKey) {
+        return logic.read(reportKey);
+    }
+
+    @Override
+    public ReportExecTO readExecution(final Long executionId) {
+        return logic.readExecution(executionId);
+    }
+
+    @Override
+    public Response exportExecutionResult(final Long executionId, final ReportExecExportFormat fmt) {
+        final ReportExecExportFormat format = (fmt == null) ? ReportExecExportFormat.XML : fmt;
+        final ReportExec reportExec = logic.getAndCheckReportExec(executionId);
+        StreamingOutput sout = new StreamingOutput() {
+
+            @Override
+            public void write(final OutputStream os) throws IOException {
+                logic.exportExecutionResult(os, reportExec, format);
+            }
+        };
+        String disposition = "attachment; filename=" + reportExec.getReport().getName() + "." + format.name().
+                toLowerCase();
+        return Response.ok(sout).
+                header(HttpHeaders.CONTENT_DISPOSITION, disposition).
+                build();
+    }
+
+    @Override
+    public ReportExecTO execute(final Long reportKey) {
+        return logic.execute(reportKey);
+    }
+
+    @Override
+    public void delete(final Long reportKey) {
+        logic.delete(reportKey);
+    }
+
+    @Override
+    public void deleteExecution(final Long executionId) {
+        logic.deleteExecution(executionId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
new file mode 100644
index 0000000..82da1a9
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ResourceServiceImpl.java
@@ -0,0 +1,151 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.wrap.PropagationActionClass;
+import org.apache.syncope.common.lib.wrap.SubjectId;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.server.logic.AbstractResourceAssociator;
+import org.apache.syncope.server.logic.ResourceLogic;
+import org.apache.syncope.server.logic.RoleLogic;
+import org.apache.syncope.server.logic.UserLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ResourceServiceImpl extends AbstractServiceImpl implements ResourceService {
+
+    @Autowired
+    private ResourceLogic logic;
+
+    @Autowired
+    private UserLogic userLogic;
+
+    @Autowired
+    private RoleLogic roleLogic;
+
+    @Override
+    public Response create(final ResourceTO resourceTO) {
+        ResourceTO created = logic.create(resourceTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(created.getKey()).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final String resourceKey, final ResourceTO resourceTO) {
+        resourceTO.setKey(resourceKey);
+        logic.update(resourceTO);
+    }
+
+    @Override
+    public void delete(final String resourceKey) {
+        logic.delete(resourceKey);
+    }
+
+    @Override
+    public ResourceTO read(final String resourceKey) {
+        return logic.read(resourceKey);
+    }
+
+    @Override
+    public List<PropagationActionClass> getPropagationActionsClasses() {
+        return CollectionWrapper.wrap(logic.getPropagationActionsClasses(), PropagationActionClass.class);
+    }
+
+    @Override
+    public List<ResourceTO> list() {
+        return logic.list(null);
+    }
+
+    @Override
+    public List<ResourceTO> list(final Long connInstanceId) {
+        return logic.list(connInstanceId);
+    }
+
+    @Override
+    public ConnObjectTO getConnectorObject(final String resourceKey, final SubjectType type, final Long key) {
+        return logic.getConnectorObject(resourceKey, type, key);
+    }
+
+    @Override
+    public boolean check(final ResourceTO resourceTO) {
+        return logic.check(resourceTO);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        return logic.bulk(bulkAction);
+    }
+
+    @Override
+    public BulkActionResult bulkDeassociation(final String resourceKey, final SubjectType subjectType,
+            final ResourceDeassociationActionType type, final List<SubjectId> subjectIds) {
+
+        AbstractResourceAssociator<? extends AbstractAttributableTO> associator = subjectType == SubjectType.USER
+                ? userLogic
+                : roleLogic;
+
+        final BulkActionResult res = new BulkActionResult();
+
+        for (SubjectId id : subjectIds) {
+            final Set<String> resources = Collections.singleton(resourceKey);
+            try {
+                switch (type) {
+                    case DEPROVISION:
+                        associator.deprovision(id.getElement(), resources);
+                        break;
+
+                    case UNASSIGN:
+                        associator.unassign(id.getElement(), resources);
+                        break;
+
+                    case UNLINK:
+                        associator.unlink(id.getElement(), resources);
+                        break;
+
+                    default:
+                }
+
+                res.add(id, BulkActionResult.Status.SUCCESS);
+            } catch (Exception e) {
+                LOG.warn("While executing {} on {} {}", type, subjectType, id.getElement(), e);
+                res.add(id, BulkActionResult.Status.FAILURE);
+            }
+        }
+
+        return res;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
new file mode 100644
index 0000000..19a4a0d
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
@@ -0,0 +1,284 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.EntityExistsException;
+import javax.persistence.PersistenceException;
+import javax.persistence.RollbackException;
+import javax.validation.ValidationException;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.validation.ValidationExceptionMapper;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ErrorTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.server.persistence.api.dao.NotFoundException;
+import org.apache.syncope.server.workflow.api.WorkflowException;
+import org.identityconnectors.framework.common.exceptions.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.transaction.TransactionSystemException;
+
+@Provider
+public class RestServiceExceptionMapper implements ExceptionMapper<Exception>, ResponseExceptionMapper<Exception> {
+
+    private static final String BASIC_REALM_UNAUTHORIZED = "Basic realm=\"Apache Syncope authentication\"";
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestServiceExceptionMapper.class);
+
+    private final ValidationExceptionMapper validationEM = new ValidationExceptionMapper();
+
+    @Override
+    public Response toResponse(final Exception ex) {
+        LOG.error("Exception thrown by REST method: " + ex.getMessage(), ex);
+
+        ResponseBuilder builder;
+
+        if (ex instanceof SyncopeClientException) {
+            SyncopeClientException sce = (SyncopeClientException) ex;
+            builder = sce.isComposite()
+                    ? getSyncopeClientCompositeExceptionResponse(sce.asComposite())
+                    : getSyncopeClientExceptionResponse(sce);
+        } else if (ex instanceof WebApplicationException) {
+            Response response = ((WebApplicationException) ex).getResponse();
+
+            ErrorTO error = new ErrorTO();
+            error.setStatus(response.getStatus());
+            error.setType(ClientExceptionType.Unknown);
+            error.getElements().add(getExMessage(ex));
+
+            builder = JAXRSUtils.fromResponse(response).entity(error);
+        } else if (ex instanceof AccessDeniedException) {
+            builder = Response.status(Response.Status.UNAUTHORIZED).
+                    header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED);
+        } else if (ex instanceof UnauthorizedRoleException) {
+            builder = builder(Response.Status.UNAUTHORIZED, ClientExceptionType.UnauthorizedRole, getExMessage(ex));
+        } else if (ex instanceof EntityExistsException) {
+            builder = builder(Response.Status.CONFLICT, ClientExceptionType.EntityExists, getExMessage(ex));
+        } else if (ex instanceof DataIntegrityViolationException) {
+            builder = builder(Response.Status.CONFLICT, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
+        } else {
+            builder = processNotFoundExceptions(ex);
+            if (builder == null) {
+                builder = processInvalidEntityExceptions(ex);
+                if (builder == null) {
+                    builder = processBadRequestExceptions(ex);
+                }
+                // process JAX-RS validation errors
+                if (builder == null && ex instanceof ValidationException) {
+                    builder = JAXRSUtils.fromResponse(validationEM.toResponse((ValidationException) ex)).
+                            header(RESTHeaders.ERROR_CODE, ClientExceptionType.RESTValidation.getHeaderValue()).
+                            header(RESTHeaders.ERROR_INFO,
+                                    ClientExceptionType.RESTValidation.getInfoHeaderValue(getExMessage(ex)));
+
+                    ErrorTO error = new ErrorTO();
+                    error.setStatus(ClientExceptionType.RESTValidation.getResponseStatus().getStatusCode());
+                    error.setType(ClientExceptionType.RESTValidation);
+                    error.getElements().add(getExMessage(ex));
+                    builder.entity(error);
+                }
+                // ...or just report as InternalServerError
+                if (builder == null) {
+                    builder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).
+                            header(RESTHeaders.ERROR_INFO,
+                                    ClientExceptionType.Unknown.getInfoHeaderValue(getExMessage(ex)));
+
+                    ErrorTO error = new ErrorTO();
+                    error.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+                    error.setType(ClientExceptionType.Unknown);
+                    error.getElements().add(getExMessage(ex));
+                    builder.entity(error);
+                }
+            }
+        }
+
+        return builder.build();
+    }
+
+    @Override
+    public Exception fromResponse(final Response r) {
+        throw new UnsupportedOperationException(
+                "Call of fromResponse() method is not expected in RestServiceExceptionMapper");
+    }
+
+    private ResponseBuilder getSyncopeClientExceptionResponse(final SyncopeClientException ex) {
+        ResponseBuilder builder = Response.status(ex.getType().getResponseStatus());
+        builder.header(RESTHeaders.ERROR_CODE, ex.getType().getHeaderValue());
+
+        ErrorTO error = new ErrorTO();
+        error.setStatus(ex.getType().getResponseStatus().getStatusCode());
+        error.setType(ex.getType());
+
+        for (String element : ex.getElements()) {
+            builder.header(RESTHeaders.ERROR_INFO, ex.getType().getInfoHeaderValue(element));
+            error.getElements().add(element);
+        }
+
+        return builder.entity(error);
+    }
+
+    private ResponseBuilder getSyncopeClientCompositeExceptionResponse(final SyncopeClientCompositeException ex) {
+        if (ex.getExceptions().size() == 1) {
+            return getSyncopeClientExceptionResponse(ex.getExceptions().iterator().next());
+        }
+
+        ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
+
+        List<ErrorTO> errors = new ArrayList<ErrorTO>();
+        for (SyncopeClientException sce : ex.getExceptions()) {
+            builder.header(RESTHeaders.ERROR_CODE, sce.getType().getHeaderValue());
+
+            ErrorTO error = new ErrorTO();
+            error.setStatus(sce.getType().getResponseStatus().getStatusCode());
+            error.setType(sce.getType());
+
+            for (String element : sce.getElements()) {
+                builder.header(RESTHeaders.ERROR_INFO, ex.getType().getInfoHeaderValue(element));
+                error.getElements().add(element);
+            }
+
+            errors.add(error);
+        }
+
+        return builder.entity(errors);
+    }
+
+    private ResponseBuilder processNotFoundExceptions(final Exception ex) {
+        if (ex instanceof javax.ws.rs.NotFoundException || ex instanceof NotFoundException) {
+            return builder(Response.Status.NOT_FOUND, ClientExceptionType.NotFound, getExMessage(ex));
+        }
+
+        return null;
+    }
+
+    private ResponseBuilder processInvalidEntityExceptions(final Exception ex) {
+        InvalidEntityException iee = null;
+
+        if (ex instanceof InvalidEntityException) {
+            iee = (InvalidEntityException) ex;
+        }
+        if (ex instanceof TransactionSystemException && ex.getCause() instanceof RollbackException
+                && ex.getCause().getCause() instanceof InvalidEntityException) {
+
+            iee = (InvalidEntityException) ex.getCause().getCause();
+        }
+
+        if (iee != null) {
+            ClientExceptionType exType =
+                    iee.getEntityClassSimpleName().endsWith("Policy")
+                            ? ClientExceptionType.InvalidPolicy
+                            : ClientExceptionType.valueOf("Invalid" + iee.getEntityClassSimpleName());
+
+            ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
+            builder.header(RESTHeaders.ERROR_CODE, exType.getHeaderValue());
+
+            ErrorTO error = new ErrorTO();
+            error.setStatus(exType.getResponseStatus().getStatusCode());
+            error.setType(exType);
+
+            for (Map.Entry<Class<?>, Set<EntityViolationType>> violation : iee.getViolations().entrySet()) {
+                for (EntityViolationType violationType : violation.getValue()) {
+                    builder.header(RESTHeaders.ERROR_INFO,
+                            exType.getInfoHeaderValue(violationType.name() + ": " + violationType.getMessage()));
+                    error.getElements().add(violationType.name() + ": " + violationType.getMessage());
+                }
+            }
+
+            return builder;
+        }
+
+        return null;
+    }
+
+    private ResponseBuilder processBadRequestExceptions(final Exception ex) {
+        ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
+
+        // This exception might be raised by Activiti (if enabled)
+        Class<?> ibatisPersistenceException = null;
+        try {
+            ibatisPersistenceException = Class.forName("org.apache.ibatis.exceptions.PersistenceException");
+        } catch (ClassNotFoundException e) {
+            // ignore
+        }
+
+        if (ex instanceof BadRequestException) {
+            if (((BadRequestException) ex).getResponse() == null) {
+                return builder;
+            } else {
+                return JAXRSUtils.fromResponse(((BadRequestException) ex).getResponse());
+            }
+        } else if (ex instanceof WorkflowException) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.Workflow, getExMessage(ex));
+        } else if (ex instanceof PersistenceException) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.GenericPersistence, getExMessage(ex));
+        } else if (ibatisPersistenceException != null && ibatisPersistenceException.isAssignableFrom(ex.getClass())) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.Workflow,
+                    getMessage(ex, "Currently unavailable. Please try later."));
+        } else if (ex instanceof JpaSystemException) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
+        } else if (ex instanceof ConfigurationException) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.InvalidConnIdConf, getExMessage(ex));
+        } else if (ex instanceof ParsingValidationException) {
+            return builder(Response.Status.BAD_REQUEST, ClientExceptionType.InvalidValues, getExMessage(ex));
+        }
+
+        return null;
+    }
+
+    private ResponseBuilder builder(final Response.Status status, final ClientExceptionType hType, final String msg) {
+        ResponseBuilder builder = Response.status(status).
+                header(RESTHeaders.ERROR_CODE, hType.getHeaderValue()).
+                header(RESTHeaders.ERROR_INFO, hType.getInfoHeaderValue(msg));
+
+        ErrorTO error = new ErrorTO();
+        error.setStatus(status.getStatusCode());
+        error.setType(hType);
+        error.getElements().add(msg);
+
+        return builder.entity(error);
+    }
+
+    private String getMessage(final Throwable ex, final String msg) {
+        return (msg == null) ? getExMessage(ex) : msg;
+    }
+
+    private String getExMessage(final Throwable ex) {
+        return (ex.getCause() == null) ? ex.getMessage() : ex.getCause().getMessage();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RoleServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RoleServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RoleServiceImpl.java
new file mode 100644
index 0000000..46ffab1
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RoleServiceImpl.java
@@ -0,0 +1,227 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.server.logic.RoleLogic;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.dao.search.SearchCond;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RoleServiceImpl extends AbstractServiceImpl implements RoleService {
+
+    @Autowired
+    private RoleLogic logic;
+
+    @Override
+    public List<RoleTO> children(final Long roleKey) {
+        return logic.children(roleKey);
+    }
+
+    @Override
+    public Response create(final RoleTO roleTO) {
+        RoleTO created = logic.create(roleTO);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public Response delete(final Long roleKey) {
+        RoleTO role = logic.read(roleKey);
+
+        checkETag(role.getETagValue());
+
+        RoleTO deleted = logic.delete(roleKey);
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public PagedResult<RoleTO> list() {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public PagedResult<RoleTO> list(final String orderBy) {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public PagedResult<RoleTO> list(final Integer page, final Integer size) {
+        return list(page, size, null);
+    }
+
+    @Override
+    public PagedResult<RoleTO> list(final Integer page, final Integer size, final String orderBy) {
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return buildPagedResult(logic.list(page, size, orderByClauses), page, size, logic.count());
+    }
+
+    @Override
+    public RoleTO parent(final Long roleKey) {
+        return logic.parent(roleKey);
+    }
+
+    @Override
+    public RoleTO read(final Long roleKey) {
+        return logic.read(roleKey);
+    }
+
+    @Override
+    public PagedResult<RoleTO> search(final String fiql) {
+        return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public PagedResult<RoleTO> search(final String fiql, final String orderBy) {
+        return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public PagedResult<RoleTO> search(final String fiql, final Integer page, final Integer size) {
+        return search(fiql, page, size, null);
+    }
+
+    @Override
+    public PagedResult<RoleTO> search(final String fiql, final Integer page, final Integer size, final String orderBy) {
+        SearchCond cond = getSearchCond(fiql);
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return buildPagedResult(
+                logic.search(cond, page, size, orderByClauses), page, size, logic.searchCount(cond));
+    }
+
+    @Override
+    public RoleTO readSelf(final Long roleKey) {
+        return logic.readSelf(roleKey);
+    }
+
+    @Override
+    public Response update(final Long roleKey, final RoleMod roleMod) {
+        RoleTO role = logic.read(roleKey);
+
+        checkETag(role.getETagValue());
+
+        roleMod.setKey(roleKey);
+        RoleTO updated = logic.update(roleMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response bulkDeassociation(
+            final Long roleKey, final ResourceDeassociationActionType type, final List<ResourceName> resourceNames) {
+
+        RoleTO role = logic.read(roleKey);
+
+        checkETag(role.getETagValue());
+
+        RoleTO updated;
+        switch (type) {
+            case UNLINK:
+                updated = logic.unlink(roleKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case UNASSIGN:
+                updated = logic.unassign(roleKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case DEPROVISION:
+                updated = logic.deprovision(roleKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            default:
+                updated = logic.read(roleKey);
+        }
+
+        final BulkActionResult res = new BulkActionResult();
+
+        if (type == ResourceDeassociationActionType.UNLINK) {
+            for (ResourceName resourceName : resourceNames) {
+                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                        ? BulkActionResult.Status.FAILURE
+                        : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+            }
+        }
+
+        return modificationResponse(res);
+    }
+
+    @Override
+    public Response bulkAssociation(
+            final Long roleKey, final ResourceAssociationActionType type, final List<ResourceName> resourceNames) {
+
+        RoleTO role = logic.read(roleKey);
+
+        checkETag(role.getETagValue());
+
+        RoleTO updated;
+        switch (type) {
+            case LINK:
+                updated = logic.link(roleKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case ASSIGN:
+                updated = logic.assign(roleKey, CollectionWrapper.unwrap(resourceNames), false, null);
+                break;
+
+            case PROVISION:
+                updated = logic.provision(roleKey, CollectionWrapper.unwrap(resourceNames), false, null);
+                break;
+
+            default:
+                updated = logic.read(roleKey);
+        }
+
+        final BulkActionResult res = new BulkActionResult();
+
+        if (type == ResourceAssociationActionType.LINK) {
+            for (ResourceName resourceName : resourceNames) {
+                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                        ? BulkActionResult.Status.FAILURE
+                        : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+            }
+        }
+
+        return modificationResponse(res);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        return logic.bulk(bulkAction);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SchemaServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SchemaServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SchemaServiceImpl.java
new file mode 100644
index 0000000..e3219e0
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SchemaServiceImpl.java
@@ -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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.server.logic.SchemaLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaService {
+
+    @Autowired
+    private SchemaLogic logic;
+
+    @Override
+    public <T extends AbstractSchemaTO> Response create(final AttributableType attrType, final SchemaType schemaType,
+            final T schemaTO) {
+
+        T created = logic.create(attrType, schemaType, schemaTO);
+
+        URI location = uriInfo.getAbsolutePathBuilder().path(created.getKey()).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void delete(final AttributableType attrType, final SchemaType schemaType, final String schemaKey) {
+        logic.delete(attrType, schemaType, schemaKey);
+    }
+
+    @Override
+    public <T extends AbstractSchemaTO> List<T> list(final AttributableType attrType, final SchemaType schemaType) {
+        return logic.list(attrType, schemaType);
+    }
+
+    @Override
+    public <T extends AbstractSchemaTO> T read(final AttributableType attrType, final SchemaType schemaType,
+            final String schemaKey) {
+
+        return logic.read(attrType, schemaType, schemaKey);
+    }
+
+    @Override
+    public <T extends AbstractSchemaTO> void update(final AttributableType attrType, final SchemaType schemaType,
+            final String schemaKey, final T schemaTO) {
+
+        schemaTO.setKey(schemaKey);
+        logic.update(attrType, schemaType, schemaTO);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SecurityQuestionServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SecurityQuestionServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SecurityQuestionServiceImpl.java
new file mode 100644
index 0000000..a24c5be
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/SecurityQuestionServiceImpl.java
@@ -0,0 +1,73 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.server.logic.SecurityQuestionLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements SecurityQuestionService {
+
+    @Autowired
+    private SecurityQuestionLogic logic;
+
+    @Override
+    public List<SecurityQuestionTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public SecurityQuestionTO read(final Long securityQuestionId) {
+        return logic.read(securityQuestionId);
+    }
+
+    @Override
+    public Response create(final SecurityQuestionTO securityQuestionTO) {
+        SecurityQuestionTO created = logic.create(securityQuestionTO);
+
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, String.valueOf(created.getKey())).
+                build();
+    }
+
+    @Override
+    public void update(final Long securityQuestionId, final SecurityQuestionTO securityQuestionTO) {
+        securityQuestionTO.setKey(securityQuestionId);
+        logic.update(securityQuestionTO);
+    }
+
+    @Override
+    public void delete(final Long securityQuestionId) {
+        logic.delete(securityQuestionId);
+    }
+
+    @Override
+    public SecurityQuestionTO readByUser(final String username) {
+        return logic.read(username);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
new file mode 100644
index 0000000..717c15d
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/TaskServiceImpl.java
@@ -0,0 +1,158 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.wrap.JobClass;
+import org.apache.syncope.common.lib.wrap.PushActionClass;
+import org.apache.syncope.common.lib.wrap.SyncActionClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.server.logic.TaskLogic;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TaskServiceImpl extends AbstractServiceImpl implements TaskService {
+
+    @Autowired
+    private TaskLogic logic;
+
+    @Override
+    public <T extends SchedTaskTO> Response create(final T taskTO) {
+        T createdTask;
+        if (taskTO instanceof SyncTaskTO || taskTO instanceof PushTaskTO || taskTO instanceof SchedTaskTO) {
+            createdTask = logic.createSchedTask(taskTO);
+        } else {
+            throw new BadRequestException();
+        }
+
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdTask.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, createdTask.getKey()).
+                build();
+    }
+
+    @Override
+    public void delete(final Long taskKey) {
+        logic.delete(taskKey);
+    }
+
+    @Override
+    public void deleteExecution(final Long executionKey) {
+        logic.deleteExecution(executionKey);
+    }
+
+    @Override
+    public TaskExecTO execute(final Long taskKey, final boolean dryRun) {
+        return logic.execute(taskKey, dryRun);
+    }
+
+    @Override
+    public List<JobClass> getJobClasses() {
+        return CollectionWrapper.wrap(logic.getJobClasses(), JobClass.class);
+    }
+
+    @Override
+    public List<SyncActionClass> getSyncActionsClasses() {
+        return CollectionWrapper.wrap(logic.getSyncActionsClasses(), SyncActionClass.class);
+    }
+
+    @Override
+    public List<PushActionClass> getPushActionsClasses() {
+        return CollectionWrapper.wrap(logic.getPushActionsClasses(), PushActionClass.class);
+    }
+
+    @Override
+    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType) {
+        return list(taskType, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType, final String orderBy) {
+        return list(taskType, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public <T extends AbstractTaskTO> PagedResult<T> list(
+            final TaskType taskType, final Integer page, final Integer size) {
+
+        return list(taskType, page, size, null);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType,
+            final Integer page, final Integer size, final String orderBy) {
+
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return (PagedResult<T>) buildPagedResult(
+                logic.list(taskType, page, size, orderByClauses), page, size, logic.count(taskType));
+    }
+
+    @Override
+    public <T extends AbstractTaskTO> T read(final Long taskKey) {
+        return logic.read(taskKey);
+    }
+
+    @Override
+    public TaskExecTO readExecution(final Long executionKey) {
+        return logic.readExecution(executionKey);
+    }
+
+    @Override
+    public void report(final Long executionKey, final ReportExecTO reportExec) {
+        reportExec.setKey(executionKey);
+        logic.report(
+                executionKey, PropagationTaskExecStatus.fromString(reportExec.getStatus()), reportExec.getMessage());
+    }
+
+    @Override
+    public void update(final Long taskKey, final AbstractTaskTO taskTO) {
+        taskTO.setKey(taskKey);
+        if (taskTO instanceof SyncTaskTO) {
+            logic.updateSync((SyncTaskTO) taskTO);
+        } else if (taskTO instanceof SchedTaskTO) {
+            logic.updateSched((SchedTaskTO) taskTO);
+        } else {
+            throw new BadRequestException();
+        }
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        return logic.bulk(bulkAction);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserSelfServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserSelfServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserSelfServiceImpl.java
new file mode 100644
index 0000000..c018d5c
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserSelfServiceImpl.java
@@ -0,0 +1,100 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.server.logic.UserLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelfService {
+
+    @Autowired
+    private UserLogic logic;
+
+    @Override
+    public Response getOptions() {
+        return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
+                header(RESTHeaders.SELFREG_ALLOWED, logic.isSelfRegAllowed()).
+                header(RESTHeaders.PWDRESET_ALLOWED, logic.isPwdResetAllowed()).
+                header(RESTHeaders.PWDRESET_NEEDS_SECURITYQUESTIONS, logic.isPwdResetRequiringSecurityQuestions()).
+                build();
+    }
+
+    @Override
+    public Response create(final UserTO userTO, final boolean storePassword) {
+        if (!logic.isSelfRegAllowed()) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+            sce.getElements().add("Self registration forbidden by configuration");
+            throw sce;
+        }
+
+        UserTO created = logic.createSelf(userTO, storePassword);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public UserTO read() {
+        return logic.readSelf();
+    }
+
+    @Override
+    public Response update(final Long userKey, final UserMod userMod) {
+        userMod.setKey(userKey);
+        UserTO updated = logic.updateSelf(userMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response delete() {
+        UserTO deleted = logic.deleteSelf();
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public void requestPasswordReset(final String username, final String securityAnswer) {
+        if (!logic.isPwdResetAllowed()) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+            sce.getElements().add("Password reset forbidden by configuration");
+            throw sce;
+        }
+
+        logic.requestPasswordReset(username, securityAnswer);
+    }
+
+    @Override
+    public void confirmPasswordReset(final String token, final String password) {
+        if (!logic.isPwdResetAllowed()) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+            sce.getElements().add("Password reset forbidden by configuration");
+            throw sce;
+        }
+
+        logic.confirmPasswordReset(token, password);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserServiceImpl.java
new file mode 100644
index 0000000..39469a3
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserServiceImpl.java
@@ -0,0 +1,251 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.server.logic.UserLogic;
+import org.apache.syncope.server.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.server.persistence.api.dao.search.SearchCond;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserServiceImpl extends AbstractServiceImpl implements UserService {
+
+    @Autowired
+    private UserLogic logic;
+
+    @Override
+    public Response getUsername(final Long userKey) {
+        return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
+                header(RESTHeaders.USERNAME, logic.getUsername(userKey)).
+                build();
+    }
+
+    @Override
+    public Response getUserId(final String username) {
+        return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
+                header(RESTHeaders.USER_ID, logic.getKey(username)).
+                build();
+    }
+
+    @Override
+    public Response create(final UserTO userTO, final boolean storePassword) {
+        UserTO created = logic.create(userTO, storePassword);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public Response delete(final Long userKey) {
+        UserTO user = logic.read(userKey);
+
+        checkETag(user.getETagValue());
+
+        UserTO deleted = logic.delete(userKey);
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public PagedResult<UserTO> list() {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public PagedResult<UserTO> list(final String orderBy) {
+        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public PagedResult<UserTO> list(final Integer page, final Integer size) {
+        return list(page, size, null);
+    }
+
+    @Override
+    public PagedResult<UserTO> list(final Integer page, final Integer size, final String orderBy) {
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return buildPagedResult(logic.list(page, size, orderByClauses), page, size, logic.count());
+    }
+
+    @Override
+    public UserTO read(final Long userKey) {
+        return logic.read(userKey);
+    }
+
+    @Override
+    public PagedResult<UserTO> search(final String fiql) {
+        return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
+    }
+
+    @Override
+    public PagedResult<UserTO> search(final String fiql, final String orderBy) {
+        return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy);
+    }
+
+    @Override
+    public PagedResult<UserTO> search(final String fiql, final Integer page, final Integer size) {
+        return search(fiql, page, size, null);
+    }
+
+    @Override
+    public PagedResult<UserTO> search(final String fiql, final Integer page, final Integer size, final String orderBy) {
+        SearchCond cond = getSearchCond(fiql);
+        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        return buildPagedResult(
+                logic.search(cond, page, size, orderByClauses), page, size, logic.searchCount(cond));
+    }
+
+    @Override
+    public Response update(final Long userKey, final UserMod userMod) {
+        UserTO user = logic.read(userKey);
+
+        checkETag(user.getETagValue());
+
+        userMod.setKey(userKey);
+        UserTO updated = logic.update(userMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response status(final Long userKey, final StatusMod statusMod) {
+        UserTO user = logic.read(userKey);
+
+        checkETag(user.getETagValue());
+
+        statusMod.setKey(userKey);
+        UserTO updated = logic.status(statusMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response bulkDeassociation(
+            final Long userKey, final ResourceDeassociationActionType type, final List<ResourceName> resourceNames) {
+
+        final UserTO user = logic.read(userKey);
+
+        checkETag(user.getETagValue());
+
+        UserTO updated;
+        switch (type) {
+            case UNLINK:
+                updated = logic.unlink(userKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case UNASSIGN:
+                updated = logic.unassign(userKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case DEPROVISION:
+                updated = logic.deprovision(userKey, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            default:
+                updated = logic.read(userKey);
+        }
+
+        final BulkActionResult res = new BulkActionResult();
+
+        if (type == ResourceDeassociationActionType.UNLINK) {
+            for (ResourceName resourceName : resourceNames) {
+                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                        ? BulkActionResult.Status.FAILURE
+                        : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+            }
+        }
+
+        return modificationResponse(res);
+    }
+
+    @Override
+    public Response bulkAssociation(
+            final Long userKey, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
+
+        final UserTO user = logic.read(userKey);
+
+        checkETag(user.getETagValue());
+
+        UserTO updated;
+        switch (type) {
+            case LINK:
+                updated = logic.link(
+                        userKey,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()));
+                break;
+
+            case ASSIGN:
+                updated = logic.assign(
+                        userKey,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            case PROVISION:
+                updated = logic.provision(
+                        userKey,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            default:
+                updated = logic.read(userKey);
+        }
+
+        final BulkActionResult res = new BulkActionResult();
+
+        if (type == ResourceAssociationActionType.LINK) {
+            for (ResourceName resourceName : associationMod.getTargetResources()) {
+                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                        ? BulkActionResult.Status.FAILURE
+                        : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+            }
+        }
+
+        return modificationResponse(res);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        return logic.bulk(bulkAction);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/8b4e52d7/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserWorkflowServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserWorkflowServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserWorkflowServiceImpl.java
new file mode 100644
index 0000000..235007d
--- /dev/null
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/UserWorkflowServiceImpl.java
@@ -0,0 +1,64 @@
+/*
+ * 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.server.rest.cxf.service;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.apache.syncope.server.logic.UserWorkflowLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserWorkflowServiceImpl implements UserWorkflowService {
+
+    @Autowired
+    private UserWorkflowLogic lofic;
+
+    @Override
+    public WorkflowFormTO claimForm(final String taskId) {
+        return lofic.claimForm(taskId);
+    }
+
+    @Override
+    public UserTO executeTask(final String taskId, final UserTO userTO) {
+        return lofic.executeWorkflowTask(userTO, taskId);
+    }
+
+    @Override
+    public WorkflowFormTO getFormForUser(final Long userKey) {
+        return lofic.getFormForUser(userKey);
+    }
+
+    @Override
+    public List<WorkflowFormTO> getForms() {
+        return lofic.getForms();
+    }
+
+    @Override
+    public UserTO submitForm(final WorkflowFormTO form) {
+        return lofic.submitForm(form);
+    }
+
+    @Override
+    public List<WorkflowFormTO> getFormsByName(final Long userKey, final String taskName) {
+        return lofic.getForms(userKey, taskName);
+    }
+}