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(); + } + +}
