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/02/12 10:14:20 UTC
[15/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming
'server' after 'core',
to provide continuity with older releases (especially for archetype)
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
new file mode 100644
index 0000000..dbfb327
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -0,0 +1,285 @@
+/*
+ * 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.cxf;
+
+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.core.misc.security.UnauthorizedRoleException;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.core.persistence.api.dao.DuplicateException;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.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 || ex instanceof DuplicateException) {
+ 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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.java
new file mode 100644
index 0000000..39f5573
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/ThreadLocalCleanupListener.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.core.rest.cxf;
+
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import org.apache.syncope.core.misc.DataFormat;
+import org.identityconnectors.common.l10n.CurrentLocale;
+import org.identityconnectors.framework.impl.api.local.ThreadClassLoaderManager;
+
+/**
+ * Remove any known thread-local variable when the servlet request is destroyed.
+ */
+public class ThreadLocalCleanupListener implements ServletRequestListener {
+
+ @Override
+ public void requestInitialized(final ServletRequestEvent sre) {
+ // nothing to do while setting up this request (and thread)
+ }
+
+ @Override
+ public void requestDestroyed(final ServletRequestEvent sre) {
+ DataFormat.clear();
+
+ ThreadClassLoaderManager.clearInstance();
+ CurrentLocale.clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
new file mode 100644
index 0000000..e5d5c74
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/WADLServlet.java
@@ -0,0 +1,96 @@
+/*
+ * 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.cxf;
+
+import java.io.IOException;
+import java.net.URL;
+import java.rmi.ServerException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.cocoon.pipeline.CachingPipeline;
+import org.apache.cocoon.pipeline.Pipeline;
+import org.apache.cocoon.sax.SAXPipelineComponent;
+import org.apache.cocoon.sax.component.XMLGenerator;
+import org.apache.cocoon.sax.component.XMLSerializer;
+import org.apache.cocoon.sax.component.XSLTTransformer;
+
+public class WADLServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -6737005675471095560L;
+
+ private static final Pattern SCHEMA_PATTERN = Pattern.compile("/schema_(.*)_(.*)\\.html");
+
+ /**
+ * Handles the HTTP <code>GET</code> method.
+ *
+ * @param request servlet request
+ * @param response servlet response
+ * @throws ServletException if a servlet-specific error occurs
+ * @throws IOException if an I/O error occurs
+ */
+ @Override
+ protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
+ throws ServletException, IOException {
+
+ String requestURI = request.getRequestURI().substring(
+ request.getRequestURI().indexOf(request.getServletPath()) + request.getServletPath().length());
+ Matcher schemaMatcher = SCHEMA_PATTERN.matcher(requestURI);
+
+ Pipeline<SAXPipelineComponent> pipeline = new CachingPipeline<SAXPipelineComponent>();
+ final String wadlURL = request.getRequestURL().
+ substring(0, request.getRequestURL().indexOf("/doc")) + "/?_wadl";
+ pipeline.addComponent(new XMLGenerator(new URL(wadlURL)));
+ if ("/".equals(requestURI)) {
+ XSLTTransformer xslt = new XSLTTransformer(getClass().getResource("/wadl2html/index.xsl"));
+
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("contextPath", request.getContextPath());
+ xslt.setParameters(parameters);
+
+ pipeline.addComponent(xslt);
+ } else if (schemaMatcher.matches()) {
+ XSLTTransformer xslt = new XSLTTransformer(getClass().getResource("/wadl2html/schema.xsl"));
+
+ Map<String, Object> parameters = new HashMap<>();
+ parameters.put("contextPath", request.getContextPath());
+ parameters.put("schema-position", schemaMatcher.group(1));
+ parameters.put("schema-prefix", schemaMatcher.group(2));
+ xslt.setParameters(parameters);
+
+ pipeline.addComponent(xslt);
+ } else {
+ throw new ServerException("URL not supported: " + request.getRequestURI());
+ }
+
+ pipeline.addComponent(XMLSerializer.createHTML4Serializer());
+ pipeline.setup(response.getOutputStream());
+ try {
+ pipeline.execute();
+ } catch (Exception e) {
+ throw new ServletException(e);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
new file mode 100644
index 0000000..f6fb69a
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.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.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.search.SearchBean;
+import org.apache.cxf.jaxrs.ext.search.SearchCondition;
+import org.apache.cxf.jaxrs.ext.search.SearchContext;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.JAXRSService;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.core.misc.search.SearchCondVisitor;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AbstractServiceImpl implements JAXRSService {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractServiceImpl.class);
+
+ protected static final String OPTIONS_ALLOW = "GET,POST,OPTIONS,HEAD";
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected MessageContext messageContext;
+
+ @Context
+ protected SearchContext searchContext;
+
+ /**
+ * Reads <tt>Prefer</tt> header from request and parses into a <tt>Preference</tt> instance.
+ *
+ * @return a <tt>Preference</tt> instance matching the passed <tt>Prefer</tt> header,
+ * or <tt>Preference.NONE</tt> if missing.
+ */
+ protected Preference getPreference() {
+ return Preference.fromString(messageContext.getHttpHeaders().getHeaderString(RESTHeaders.PREFER));
+ }
+
+ /**
+ * Builds response to successful <tt>create</tt> request, taking into account any <tt>Prefer</tt> header.
+ *
+ * @param id identifier of the created entity
+ * @param entity the entity just created
+ * @return response to successful <tt>create</tt> request
+ */
+ protected Response createResponse(final Object id, final Object entity) {
+ URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(id)).build();
+
+ Response.ResponseBuilder builder = Response.
+ created(location).
+ header(RESTHeaders.RESOURCE_ID, id);
+
+ switch (getPreference()) {
+ case RETURN_NO_CONTENT:
+ break;
+
+ case RETURN_CONTENT:
+ case NONE:
+ default:
+ builder = builder.entity(entity);
+ break;
+
+ }
+ if (getPreference() == Preference.RETURN_CONTENT || getPreference() == Preference.RETURN_NO_CONTENT) {
+ builder = builder.header(RESTHeaders.PREFERENCE_APPLIED, getPreference().toString());
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Builds response to successful modification request, taking into account any <tt>Prefer</tt> header.
+ *
+ * @param entity the entity just modified
+ * @return response to successful modification request
+ */
+ protected Response modificationResponse(final Object entity) {
+ Response.ResponseBuilder builder;
+ switch (getPreference()) {
+ case RETURN_NO_CONTENT:
+ builder = Response.noContent();
+ break;
+
+ case RETURN_CONTENT:
+ case NONE:
+ default:
+ builder = Response.ok(entity);
+ break;
+ }
+ if (getPreference() == Preference.RETURN_CONTENT || getPreference() == Preference.RETURN_NO_CONTENT) {
+ builder = builder.header(RESTHeaders.PREFERENCE_APPLIED, getPreference().toString());
+ }
+
+ return builder.build();
+ }
+
+ protected void checkETag(final String etag) {
+ Response.ResponseBuilder builder = messageContext.getRequest().evaluatePreconditions(new EntityTag(etag));
+ if (builder != null) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.ConcurrentModification);
+ sce.getElements().add("Mismatching ETag value");
+ throw sce;
+ }
+ }
+
+ protected SearchCond getSearchCond(final String fiql) {
+ try {
+ SearchCondVisitor visitor = new SearchCondVisitor();
+ SearchCondition<SearchBean> sc = searchContext.getCondition(fiql, SearchBean.class);
+ sc.accept(visitor);
+
+ return visitor.getQuery();
+ } catch (Exception e) {
+ LOG.error("Invalid FIQL expression: {}", fiql, e);
+
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSearchExpression);
+ sce.getElements().add(fiql);
+ throw sce;
+ }
+ }
+
+ protected List<OrderByClause> getOrderByClauses(final String orderBy) {
+ if (StringUtils.isBlank(orderBy)) {
+ return Collections.<OrderByClause>emptyList();
+ }
+
+ List<OrderByClause> result = new ArrayList<>();
+
+ for (String clause : orderBy.split(",")) {
+ String[] elems = clause.split(" ");
+
+ if (elems.length > 0 && StringUtils.isNotBlank(elems[0])) {
+ OrderByClause obc = new OrderByClause();
+ obc.setField(elems[0].trim());
+ if (elems.length > 1 && StringUtils.isNotBlank(elems[1])) {
+ obc.setDirection(elems[1].trim().equalsIgnoreCase(OrderByClause.Direction.ASC.name())
+ ? OrderByClause.Direction.ASC : OrderByClause.Direction.DESC);
+ }
+ result.add(obc);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Builds a paged result out of a list of items and additional information.
+ *
+ * @param <T> result type
+ * @param list bare list of items to be returned
+ * @param page current page
+ * @param size requested size
+ * @param totalCount total result size (not considering pagination)
+ * @return paged result
+ */
+ protected <T extends AbstractBaseBean> PagedResult<T> buildPagedResult(
+ final List<T> list, final int page, final int size, final int totalCount) {
+
+ PagedResult<T> result = new PagedResult<>();
+ result.getResult().addAll(list);
+
+ result.setPage(page);
+ result.setSize(result.getResult().size());
+ result.setTotalCount(totalCount);
+
+ UriBuilder builder = uriInfo.getAbsolutePathBuilder();
+ MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
+ for (Map.Entry<String, List<String>> queryParam : queryParams.entrySet()) {
+ builder = builder.queryParam(queryParam.getKey(), queryParam.getValue().toArray());
+ }
+
+ if (result.getPage() > 1) {
+ result.setPrev(builder.
+ replaceQueryParam(PARAM_PAGE, result.getPage() - 1).
+ replaceQueryParam(PARAM_SIZE, size).
+ build());
+ }
+ if ((result.getPage() - 1) * size + result.getSize() < totalCount) {
+ result.setNext(builder.
+ replaceQueryParam(PARAM_PAGE, result.getPage() + 1).
+ replaceQueryParam(PARAM_SIZE, size).
+ build());
+ }
+
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
new file mode 100644
index 0000000..bdb40ac
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AddETagFilter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.cxf.service;
+
+import java.io.IOException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.ext.Provider;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
+
+/**
+ * Adds the <tt>ETag</tt> filter to any response containing an instance of <tt>AbstractSysInfoTO</tt> as entity.
+ * The actual ETag value is computed on the basis of last change date (or creation date if not available).
+ *
+ * @see AbstractSysInfoTO
+ */
+@Provider
+public class AddETagFilter implements ContainerResponseFilter {
+
+ @Override
+ public void filter(final ContainerRequestContext reqCtx, final ContainerResponseContext resCtx) throws IOException {
+ if (resCtx.getEntity() instanceof AbstractAnnotatedBean && resCtx.getEntityTag() == null) {
+ AbstractAnnotatedBean sysInfo = (AbstractAnnotatedBean) resCtx.getEntity();
+ String etagValue = sysInfo.getETagValue();
+ if (StringUtils.isNotBlank(etagValue)) {
+ resCtx.getHeaders().add(HttpHeaders.ETAG, new EntityTag(etagValue).toString());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConfigurationServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConfigurationServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConfigurationServiceImpl.java
new file mode 100644
index 0000000..90bb6be
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConfigurationServiceImpl.java
@@ -0,0 +1,77 @@
+/*
+ * 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.cxf.service;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConfTO;
+import org.apache.syncope.common.rest.api.service.ConfigurationService;
+import org.apache.syncope.core.logic.ConfigurationLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ConfigurationServiceImpl extends AbstractServiceImpl implements ConfigurationService {
+
+ private static final String CONTENT_XML = "content.xml";
+
+ @Autowired
+ private ConfigurationLogic logic;
+
+ @Override
+ public Response export() {
+ StreamingOutput sout = new StreamingOutput() {
+
+ @Override
+ public void write(final OutputStream os) throws IOException {
+ logic.export(os);
+ }
+ };
+ return Response.ok(sout).
+ type(MediaType.TEXT_XML).
+ header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + CONTENT_XML).
+ build();
+ }
+
+ @Override
+ public void delete(final String key) {
+ logic.delete(key);
+ }
+
+ @Override
+ public ConfTO list() {
+ return logic.list();
+ }
+
+ @Override
+ public AttrTO read(final String key) {
+ return logic.read(key);
+ }
+
+ @Override
+ public void set(final String key, final AttrTO value) {
+ value.setSchema(key);
+ logic.set(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
new file mode 100644
index 0000000..1ba5674
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/EntitlementServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/EntitlementServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/EntitlementServiceImpl.java
new file mode 100644
index 0000000..8d2b2a4
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/LoggerServiceImpl.java
new file mode 100644
index 0000000..2ae9136
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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.getKey().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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
new file mode 100644
index 0000000..4691189
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
new file mode 100644
index 0000000..ac4df8a
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
@@ -0,0 +1,118 @@
+/*
+ * 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.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.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.core.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, 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;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
new file mode 100644
index 0000000..3fd69a4
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.logic.ReportLogic;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.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 executionKey) {
+ return logic.readExecution(executionKey);
+ }
+
+ @Override
+ public Response exportExecutionResult(final Long executionKey, final ReportExecExportFormat fmt) {
+ final ReportExecExportFormat format = (fmt == null) ? ReportExecExportFormat.XML : fmt;
+ final ReportExec reportExec = logic.getAndCheckReportExec(executionKey);
+ 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 executionKey) {
+ logic.deleteExecution(executionKey);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
new file mode 100644
index 0000000..1feee38
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -0,0 +1,139 @@
+/*
+ * 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.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.SubjectKey;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.core.logic.AbstractResourceAssociator;
+import org.apache.syncope.core.logic.ResourceLogic;
+import org.apache.syncope.core.logic.RoleLogic;
+import org.apache.syncope.core.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<ResourceTO> list() {
+ return logic.list();
+ }
+
+ @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<SubjectKey> subjectKeys) {
+
+ AbstractResourceAssociator<? extends AbstractAttributableTO> associator = subjectType == SubjectType.USER
+ ? userLogic
+ : roleLogic;
+
+ final BulkActionResult res = new BulkActionResult();
+
+ for (SubjectKey key : subjectKeys) {
+ final Set<String> resources = Collections.singleton(resourceKey);
+ try {
+ switch (type) {
+ case DEPROVISION:
+ associator.deprovision(key.getElement(), resources);
+ break;
+
+ case UNASSIGN:
+ associator.unassign(key.getElement(), resources);
+ break;
+
+ case UNLINK:
+ associator.unlink(key.getElement(), resources);
+ break;
+
+ default:
+ }
+
+ res.add(key, BulkActionResult.Status.SUCCESS);
+ } catch (Exception e) {
+ LOG.warn("While executing {} on {} {}", type, subjectType, key.getElement(), e);
+ res.add(key, BulkActionResult.Status.FAILURE);
+ }
+ }
+
+ return res;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
new file mode 100644
index 0000000..b42fc2f
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.logic.RoleLogic;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SchemaServiceImpl.java
new file mode 100644
index 0000000..3082c94
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
new file mode 100644
index 0000000..70666b6
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
new file mode 100644
index 0000000..8227584
--- /dev/null
+++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SyncopeServiceImpl.java
@@ -0,0 +1,38 @@
+/*
+ * 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.cxf.service;
+
+import org.apache.syncope.common.lib.to.SyncopeTO;
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+import org.apache.syncope.core.logic.SyncopeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SyncopeServiceImpl extends AbstractServiceImpl implements SyncopeService {
+
+ @Autowired
+ private SyncopeLogic logic;
+
+ @Override
+ public SyncopeTO info() {
+ return logic.info();
+ }
+
+}