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/TaskServiceImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java new file mode 100644 index 0000000..3867a25 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.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.List; +import javax.ws.rs.BadRequestException; +import javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.to.AbstractTaskTO; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.PagedResult; +import org.apache.syncope.common.lib.to.PushTaskTO; +import org.apache.syncope.common.lib.to.ReportExecTO; +import org.apache.syncope.common.lib.to.SchedTaskTO; +import org.apache.syncope.common.lib.to.SyncTaskTO; +import org.apache.syncope.common.lib.to.TaskExecTO; +import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; +import org.apache.syncope.common.lib.types.TaskType; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.TaskService; +import org.apache.syncope.core.logic.TaskLogic; +import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class TaskServiceImpl extends AbstractServiceImpl implements TaskService { + + @Autowired + private TaskLogic logic; + + @Override + public <T extends SchedTaskTO> Response create(final T taskTO) { + T createdTask; + if (taskTO instanceof SyncTaskTO || taskTO instanceof PushTaskTO || taskTO instanceof SchedTaskTO) { + createdTask = logic.createSchedTask(taskTO); + } else { + throw new BadRequestException(); + } + + URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdTask.getKey())).build(); + return Response.created(location). + header(RESTHeaders.RESOURCE_ID, createdTask.getKey()). + build(); + } + + @Override + public void delete(final Long taskKey) { + logic.delete(taskKey); + } + + @Override + public void deleteExecution(final Long executionKey) { + logic.deleteExecution(executionKey); + } + + @Override + public TaskExecTO execute(final Long taskKey, final boolean dryRun) { + return logic.execute(taskKey, dryRun); + } + + @Override + public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType) { + return list(taskType, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null); + } + + @Override + public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType, final String orderBy) { + return list(taskType, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy); + } + + @Override + public <T extends AbstractTaskTO> PagedResult<T> list( + final TaskType taskType, final Integer page, final Integer size) { + + return list(taskType, page, size, null); + } + + @Override + @SuppressWarnings("unchecked") + public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType taskType, + final Integer page, final Integer size, final String orderBy) { + + List<OrderByClause> orderByClauses = getOrderByClauses(orderBy); + return (PagedResult<T>) buildPagedResult( + logic.list(taskType, page, size, orderByClauses), page, size, logic.count(taskType)); + } + + @Override + public <T extends AbstractTaskTO> T read(final Long taskKey) { + return logic.read(taskKey); + } + + @Override + public TaskExecTO readExecution(final Long executionKey) { + return logic.readExecution(executionKey); + } + + @Override + public void report(final Long executionKey, final ReportExecTO reportExec) { + reportExec.setKey(executionKey); + logic.report( + executionKey, PropagationTaskExecStatus.fromString(reportExec.getStatus()), reportExec.getMessage()); + } + + @Override + public void update(final Long taskKey, final AbstractTaskTO taskTO) { + taskTO.setKey(taskKey); + if (taskTO instanceof SyncTaskTO) { + logic.updateSync((SyncTaskTO) taskTO); + } else if (taskTO instanceof SchedTaskTO) { + logic.updateSched((SchedTaskTO) taskTO); + } else { + throw new BadRequestException(); + } + } + + @Override + public BulkActionResult bulk(final BulkAction bulkAction) { + return logic.bulk(bulkAction); + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java new file mode 100644 index 0000000..f48ec4c --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java @@ -0,0 +1,93 @@ +/* + * 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 javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.mod.UserMod; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.rest.api.service.UserSelfService; +import org.apache.syncope.core.logic.SyncopeLogic; +import org.apache.syncope.core.logic.UserLogic; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelfService { + + @Autowired + private UserLogic logic; + + @Autowired + private SyncopeLogic syncopeLogic; + + @Override + public Response create(final UserTO userTO, final boolean storePassword) { + if (!syncopeLogic.isSelfRegAllowed()) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized); + sce.getElements().add("Self registration forbidden by configuration"); + throw sce; + } + + UserTO created = logic.createSelf(userTO, storePassword); + return createResponse(created.getKey(), created); + } + + @Override + public UserTO read() { + return logic.readSelf(); + } + + @Override + public Response update(final Long userKey, final UserMod userMod) { + userMod.setKey(userKey); + UserTO updated = logic.updateSelf(userMod); + return modificationResponse(updated); + } + + @Override + public Response delete() { + UserTO deleted = logic.deleteSelf(); + return modificationResponse(deleted); + } + + @Override + public void requestPasswordReset(final String username, final String securityAnswer) { + if (!syncopeLogic.isPwdResetAllowed()) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized); + sce.getElements().add("Password reset forbidden by configuration"); + throw sce; + } + + logic.requestPasswordReset(username, securityAnswer); + } + + @Override + public void confirmPasswordReset(final String token, final String password) { + if (!syncopeLogic.isPwdResetAllowed()) { + SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized); + sce.getElements().add("Password reset forbidden by configuration"); + throw sce; + } + + logic.confirmPasswordReset(token, password); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java new file mode 100644 index 0000000..82cecfc --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.rest.cxf.service; + +import java.util.List; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.mod.ResourceAssociationMod; +import org.apache.syncope.common.lib.mod.StatusMod; +import org.apache.syncope.common.lib.mod.UserMod; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.PagedResult; +import org.apache.syncope.common.lib.to.PropagationStatus; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.ResourceAssociationActionType; +import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; +import org.apache.syncope.common.lib.wrap.ResourceName; +import org.apache.syncope.common.rest.api.CollectionWrapper; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.UserService; +import org.apache.syncope.core.logic.UserLogic; +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 UserServiceImpl extends AbstractServiceImpl implements UserService { + + @Autowired + private UserLogic logic; + + @Override + public Response getUsername(final Long userKey) { + return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW). + header(RESTHeaders.USERNAME, logic.getUsername(userKey)). + build(); + } + + @Override + public Response getUserId(final String username) { + return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW). + header(RESTHeaders.USER_ID, logic.getKey(username)). + build(); + } + + @Override + public Response create(final UserTO userTO, final boolean storePassword) { + UserTO created = logic.create(userTO, storePassword); + return createResponse(created.getKey(), created); + } + + @Override + public Response delete(final Long userKey) { + UserTO user = logic.read(userKey); + + checkETag(user.getETagValue()); + + UserTO deleted = logic.delete(userKey); + return modificationResponse(deleted); + } + + @Override + public PagedResult<UserTO> list() { + return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null); + } + + @Override + public PagedResult<UserTO> list(final String orderBy) { + return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy); + } + + @Override + public PagedResult<UserTO> list(final Integer page, final Integer size) { + return list(page, size, null); + } + + @Override + public PagedResult<UserTO> list(final Integer page, final Integer size, final String orderBy) { + List<OrderByClause> orderByClauses = getOrderByClauses(orderBy); + return buildPagedResult(logic.list(page, size, orderByClauses), page, size, logic.count()); + } + + @Override + public UserTO read(final Long userKey) { + return logic.read(userKey); + } + + @Override + public PagedResult<UserTO> search(final String fiql) { + return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null); + } + + @Override + public PagedResult<UserTO> search(final String fiql, final String orderBy) { + return search(fiql, DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, orderBy); + } + + @Override + public PagedResult<UserTO> search(final String fiql, final Integer page, final Integer size) { + return search(fiql, page, size, null); + } + + @Override + public PagedResult<UserTO> search(final String fiql, final Integer page, final Integer size, final String orderBy) { + SearchCond cond = getSearchCond(fiql); + List<OrderByClause> orderByClauses = getOrderByClauses(orderBy); + return buildPagedResult( + logic.search(cond, page, size, orderByClauses), page, size, logic.searchCount(cond)); + } + + @Override + public Response update(final Long userKey, final UserMod userMod) { + UserTO user = logic.read(userKey); + + checkETag(user.getETagValue()); + + userMod.setKey(userKey); + UserTO updated = logic.update(userMod); + return modificationResponse(updated); + } + + @Override + public Response status(final Long userKey, final StatusMod statusMod) { + UserTO user = logic.read(userKey); + + checkETag(user.getETagValue()); + + statusMod.setKey(userKey); + UserTO updated = logic.status(statusMod); + return modificationResponse(updated); + } + + @Override + public Response bulkDeassociation( + final Long userKey, final ResourceDeassociationActionType type, final List<ResourceName> resourceNames) { + + final UserTO user = logic.read(userKey); + + checkETag(user.getETagValue()); + + UserTO updated; + switch (type) { + case UNLINK: + updated = logic.unlink(userKey, CollectionWrapper.unwrap(resourceNames)); + break; + + case UNASSIGN: + updated = logic.unassign(userKey, CollectionWrapper.unwrap(resourceNames)); + break; + + case DEPROVISION: + updated = logic.deprovision(userKey, CollectionWrapper.unwrap(resourceNames)); + break; + + default: + updated = logic.read(userKey); + } + + final BulkActionResult res = new BulkActionResult(); + + if (type == ResourceDeassociationActionType.UNLINK) { + for (ResourceName resourceName : resourceNames) { + res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement()) + ? BulkActionResult.Status.FAILURE + : BulkActionResult.Status.SUCCESS); + } + } else { + for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { + res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString()); + } + } + + return modificationResponse(res); + } + + @Override + public Response bulkAssociation( + final Long userKey, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) { + + final UserTO user = logic.read(userKey); + + checkETag(user.getETagValue()); + + UserTO updated; + switch (type) { + case LINK: + updated = logic.link( + userKey, + CollectionWrapper.unwrap(associationMod.getTargetResources())); + break; + + case ASSIGN: + updated = logic.assign( + userKey, + CollectionWrapper.unwrap(associationMod.getTargetResources()), + associationMod.isChangePwd(), + associationMod.getPassword()); + break; + + case PROVISION: + updated = logic.provision( + userKey, + CollectionWrapper.unwrap(associationMod.getTargetResources()), + associationMod.isChangePwd(), + associationMod.getPassword()); + break; + + default: + updated = logic.read(userKey); + } + + final BulkActionResult res = new BulkActionResult(); + + if (type == ResourceAssociationActionType.LINK) { + for (ResourceName resourceName : associationMod.getTargetResources()) { + res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement()) + ? BulkActionResult.Status.FAILURE + : BulkActionResult.Status.SUCCESS); + } + } else { + for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { + res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString()); + } + } + + return modificationResponse(res); + } + + @Override + public BulkActionResult bulk(final BulkAction bulkAction) { + return logic.bulk(bulkAction); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java new file mode 100644 index 0000000..cc70e16 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.rest.cxf.service; + +import java.util.List; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.to.WorkflowFormTO; +import org.apache.syncope.common.rest.api.service.UserWorkflowService; +import org.apache.syncope.core.logic.UserWorkflowLogic; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UserWorkflowServiceImpl implements UserWorkflowService { + + @Autowired + private UserWorkflowLogic lofic; + + @Override + public WorkflowFormTO claimForm(final String taskId) { + return lofic.claimForm(taskId); + } + + @Override + public UserTO executeTask(final String taskId, final UserTO userTO) { + return lofic.executeWorkflowTask(userTO, taskId); + } + + @Override + public WorkflowFormTO getFormForUser(final Long userKey) { + return lofic.getFormForUser(userKey); + } + + @Override + public List<WorkflowFormTO> getForms() { + return lofic.getForms(); + } + + @Override + public UserTO submitForm(final WorkflowFormTO form) { + return lofic.submitForm(form); + } + + @Override + public List<WorkflowFormTO> getFormsByName(final Long userKey, final String taskName) { + return lofic.getForms(userKey, taskName); + } +} 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/WorkflowServiceImpl.java ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.java new file mode 100644 index 0000000..d3a44e4 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/WorkflowServiceImpl.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.service; + +import java.io.IOException; +import java.io.OutputStream; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.WorkflowService; +import org.apache.syncope.core.logic.WorkflowLogic; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WorkflowServiceImpl extends AbstractServiceImpl implements WorkflowService { + + @Autowired + private WorkflowLogic logic; + + @Override + public Response exportDefinition(final SubjectType kind) { + final MediaType accept = + messageContext.getHttpHeaders().getAcceptableMediaTypes().contains(MediaType.APPLICATION_JSON_TYPE) + ? MediaType.APPLICATION_JSON_TYPE + : MediaType.APPLICATION_XML_TYPE; + + StreamingOutput sout = new StreamingOutput() { + + @Override + public void write(final OutputStream os) throws IOException { + if (kind == SubjectType.USER) { + logic.exportUserDefinition(accept, os); + } else { + logic.exportRoleDefinition(accept, os); + } + } + }; + + return Response.ok(sout). + type(accept). + build(); + } + + @Override + public Response exportDiagram(final SubjectType kind) { + StreamingOutput sout = new StreamingOutput() { + + @Override + public void write(final OutputStream os) throws IOException { + if (kind == SubjectType.USER) { + logic.exportUserDiagram(os); + } else { + logic.exportRoleDiagram(os); + } + } + }; + + return Response.ok(sout). + type(RESTHeaders.MEDIATYPE_IMAGE_PNG). + build(); + } + + @Override + public void importDefinition(final SubjectType kind, final String definition) { + final MediaType contentType = + messageContext.getHttpHeaders().getMediaType().equals(MediaType.APPLICATION_JSON_TYPE) + ? MediaType.APPLICATION_JSON_TYPE + : MediaType.APPLICATION_XML_TYPE; + + if (kind == SubjectType.USER) { + logic.importUserDefinition(contentType, definition); + } else { + logic.importRoleDefinition(contentType, definition); + } + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/syncope620/core/rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger new file mode 100644 index 0000000..6e7bd36 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger @@ -0,0 +1 @@ +org.apache.cxf.common.logging.Slf4jLogger http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/resources/META-INF/web-fragment.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/resources/META-INF/web-fragment.xml b/syncope620/core/rest-cxf/src/main/resources/META-INF/web-fragment.xml new file mode 100644 index 0000000..da72c97 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/resources/META-INF/web-fragment.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd" + id="${pom.artifactId}" version="3.1"> + + <display-name>Apache Syncope ${syncope.version} Server</display-name> + + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value>classpath*:/*Context.xml</param-value> + </context-param> + + <listener> + <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> + </listener> + <listener> + <listener-class>org.apache.syncope.core.rest.cxf.ThreadLocalCleanupListener</listener-class> + </listener> + + <servlet> + <servlet-name>CXFServlet</servlet-name> + <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + <servlet-mapping> + <servlet-name>CXFServlet</servlet-name> + <url-pattern>/rest/*</url-pattern> + </servlet-mapping> + <servlet> + <servlet-name>WADLServlet</servlet-name> + <servlet-class>org.apache.syncope.core.rest.cxf.WADLServlet</servlet-class> + <load-on-startup>2</load-on-startup> + </servlet> + <servlet-mapping> + <servlet-name>WADLServlet</servlet-name> + <url-pattern>/rest/doc/*</url-pattern> + </servlet-mapping> + + <filter> + <filter-name>encodingFilter</filter-name> + <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> + <init-param> + <param-name>encoding</param-name> + <param-value>UTF-8</param-value> + </init-param> + <init-param> + <param-name>forceEncoding</param-name> + <param-value>true</param-value> + </init-param> + </filter> + <filter> + <filter-name>springSecurityFilterChain</filter-name> + <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> + </filter> + + <filter-mapping> + <filter-name>encodingFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <filter-mapping> + <filter-name>springSecurityFilterChain</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <login-config> + <auth-method>CLIENT-CERT</auth-method> + </login-config> + +</web-fragment> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/resources/restCXFContext.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/resources/restCXFContext.xml b/syncope620/core/rest-cxf/src/main/resources/restCXFContext.xml new file mode 100644 index 0000000..e5e14d6 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/resources/restCXFContext.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jaxrs="http://cxf.apache.org/jaxrs" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://cxf.apache.org/jaxrs + http://cxf.apache.org/schemas/jaxrs.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop.xsd"> + + <import resource="classpath:META-INF/cxf/cxf.xml"/> + <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> + + <context:component-scan base-package="org.apache.syncope.core.rest.cxf.service"/> + + <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider"> + <property name="namespacePrefixes"> + <map> + <entry key="http://syncope.apache.org/2.0"> + <value>syncope</value> + </entry> + </map> + </property> + <property name="depthProperties"> + <bean id="depthProperties" class="org.apache.cxf.staxutils.DocumentDepthProperties"> + <property name="innerElementCountThreshold" value="500"/> + </bean> + </property> + <property name="collectionWrapperMap"> + <map> + <entry> + <key> + <value>org.apache.syncope.common.lib.to.AbstractPolicyTO</value> + </key> + <value>policies</value> + </entry> + </map> + </property> + </bean> + + <bean id="jacksonObjectMapper" class="org.apache.syncope.core.misc.serialization.UnwrappedObjectMapper"/> + <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"> + <property name="mapper" ref="jacksonObjectMapper"/> + </bean> + + <bean id="exceptionMapper" class="org.apache.syncope.core.rest.cxf.RestServiceExceptionMapper"/> + + <bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider"/> + <bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor"> + <property name="provider" ref="validationProvider"/> + </bean> + <bean id="validationOutInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor"> + <property name="provider" ref="validationProvider"/> + </bean> + + <bean id="searchContextProvider" class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider"/> + + <bean id="wadlGenerator" class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator"> + <property name="applicationTitle" value="Apache Syncope ${syncope.version}"/> + <property name="namespacePrefix" value="syncope"/> + <property name="linkJsonToXmlSchema" value="true"/> + <property name="useJaxbContextForQnames" value="true"/> + <property name="ignoreMessageWriters" value="true"/> + <property name="addResourceAndMethodIds" value="true"/> + <property name="javaDocPath" value="/WEB-INF/lib/syncope-common-rest-api-${syncope.version}-javadoc.jar"/> + </bean> + + <bean id="addETagFilter" class="org.apache.syncope.core.rest.cxf.service.AddETagFilter"/> + + <jaxrs:server id="restContainer" address="/" + basePackages="org.apache.syncope.common.rest.api.service, org.apache.syncope.core.rest.cxf.service" + staticSubresourceResolution="true"> + <jaxrs:resourceComparator> + <bean class="org.apache.syncope.core.rest.cxf.QueryResourceInfoComparator"/> + </jaxrs:resourceComparator> + <jaxrs:properties> + <entry key="search.lax.property.match" value="true"/> + </jaxrs:properties> + <jaxrs:inInterceptors> + <ref bean="validationInInterceptor"/> + </jaxrs:inInterceptors> + <jaxrs:outInterceptors> + <ref bean="validationOutInterceptor"/> + </jaxrs:outInterceptors> + <jaxrs:providers> + <ref bean="jaxbProvider"/> + <ref bean="jsonProvider"/> + <ref bean="exceptionMapper"/> + <ref bean="searchContextProvider"/> + <ref bean="wadlGenerator"/> + <ref bean="addETagFilter"/> + </jaxrs:providers> + <jaxrs:extensionMappings> + <entry key="json" value="application/json;charset=UTF-8"/> + <entry key="xml" value="application/xml;charset=UTF-8"/> + </jaxrs:extensionMappings> + </jaxrs:server> + +</beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/resources/wadl2html/index.xsl ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/resources/wadl2html/index.xsl b/syncope620/core/rest-cxf/src/main/resources/wadl2html/index.xsl new file mode 100644 index 0000000..e238b99 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/resources/wadl2html/index.xsl @@ -0,0 +1,484 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xalan="http://xml.apache.org/xalan" + xmlns:wadl="http://wadl.dev.java.net/2009/02" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + exclude-result-prefixes="xalan wadl xs" + version="1.0"> + + <xsl:param name="contextPath"/> + + <xsl:variable name="namespaces"> + <xsl:for-each select="/*/namespace::*"> + <namespace prefix="{name()}" url="{.}"/> + </xsl:for-each> + </xsl:variable> + + <xsl:variable name="namespacePos"> + <xsl:for-each select="//xs:schema"> + <namespace url="{@targetNamespace}" position="{position()}"/> + </xsl:for-each> + </xsl:variable> + + <xsl:template match="/wadl:application"> + <html lang="en"> + <head> + <meta charset="utf-8"/> + <title> + <xsl:value-of select="wadl:doc/@title"/> + </title> + + <link rel="stylesheet" href="{$contextPath}/webjars/jquery-ui/${jquery-ui.version}/themes/base/minified/jquery-ui.min.css"/> + <style> + body { + font-family: "Verdana,Arial,sans-serif"; + font-size: 0.9em; + } + + table { + font-family: "Verdana,Arial,sans-serif"; + font-size: 0.9em; + border-width: 1px; + border-color: #666666; + border-collapse: collapse; + } + table th { + border-width: 1px; + padding: 8px; + border-style: solid; + border-color: #666666; + background-color: #dedede; + } + td { + border-width: 1px; + padding: 8px; + border-style: solid; + border-color: #666666; + background-color: #ffffff; + vertical-align: top; + } + + .methods { + padding: 5px; + } + + .representation-label { + font-weight: bold; + width: 80px; + } + + .ui-widget { font-size: 0.9em; } + .ui-tabs-vertical { width: 60em; } + .ui-tabs-vertical .ui-tabs-nav { padding: .2em .1em .2em .2em; float: left; width: 15em; } + .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 1px !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; } + .ui-tabs-vertical .ui-tabs-nav li a { display:block; } + .ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { padding-bottom: 0; padding-right: .1em; border-right-width: 1px; border-right-width: 1px; } + .ui-tabs-vertical .ui-tabs-panel { padding: 1em; float: right; width: 40em;} + </style> + + <script src="{$contextPath}/webjars/jquery/${jquery.version}/jquery.min.js"> + </script> + <script src="{$contextPath}/webjars/jquery-ui/${jquery-ui.version}/ui/minified/jquery-ui.min.js"> + </script> + <script> + //<![CDATA[ + $(function() { + //]]> + <xsl:for-each select="wadl:resources/wadl:resource"> + <xsl:sort select="@path"/> + <xsl:text>$( "#accordion-</xsl:text> + <xsl:value-of select="position()"/> + <xsl:text>" ).accordion({ + collapsible: true, + heightStyle: "content", + active: false + }); + </xsl:text> + + <xsl:variable name="parentResourcePath" select="translate(@path, '/{}', '___')"/> + <xsl:call-template name="dialog-init"> + <xsl:with-param name="resourcePath" select="$parentResourcePath"/> + </xsl:call-template> + <xsl:for-each select="wadl:resource"> + <xsl:variable name="childResourcePath" select="translate(@path, '/{}', '___')"/> + <xsl:call-template name="dialog-init"> + <xsl:with-param name="resourcePath" select="concat($parentResourcePath, $childResourcePath)"/> + </xsl:call-template> + </xsl:for-each> + </xsl:for-each> + //<![CDATA[ + $( "#tabs" ).tabs().addClass( "ui-tabs-vertical ui-helper-clearfix" ); + $( "#tabs li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" ); + }); + + /* + * hoverIntent | Copyright 2011 Brian Cherne + * http://cherne.net/brian/resources/jquery.hoverIntent.html + * modified by the jQuery UI team + */ + $.event.special.hoverintent = { + setup: function() { + $( this ).bind( "mouseover", jQuery.event.special.hoverintent.handler ); + }, + teardown: function() { + $( this ).unbind( "mouseover", jQuery.event.special.hoverintent.handler ); + }, + handler: function( event ) { + var currentX, currentY, timeout, + args = arguments, + target = $( event.target ), + previousX = event.pageX, + previousY = event.pageY; + + function track( event ) { + currentX = event.pageX; + currentY = event.pageY; + }; + + function clear() { + target + .unbind( "mousemove", track ) + .unbind( "mouseout", clear ); + clearTimeout( timeout ); + } + + function handler() { + var prop, + orig = event; + + if ( ( Math.abs( previousX - currentX ) + + Math.abs( previousY - currentY ) ) < 7 ) { + clear(); + + event = $.Event( "hoverintent" ); + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + // Prevent accessing the original event since the new event + // is fired asynchronously and the old event is no longer + // usable (#6028) + delete event.originalEvent; + + target.trigger( event ); + } else { + previousX = currentX; + previousY = currentY; + timeout = setTimeout( handler, 100 ); + } + } + + timeout = setTimeout( handler, 100 ); + target.bind({ + mousemove: track, + mouseout: clear + }); + } + }; + //]]> + </script> + </head> + <body> + <h1> + <xsl:value-of select="wadl:doc/@title"/> + </h1> + + <h3>Namespaces</h3> + <table> + <tr> + <th>Prefix</th> + <th>URI</th> + <th>XSD</th> + </tr> + <xsl:apply-templates select="wadl:grammars/xs:schema"/> + </table> + + <h3>REST resources</h3> + <div id="tabs"> + <ul> + <xsl:for-each select="wadl:resources/wadl:resource"> + <xsl:sort select="@path"/> + <li> + <a href="#tabs-{position()}"> + <xsl:value-of select="@path"/> + </a> + </li> + </xsl:for-each> + </ul> + + <xsl:apply-templates select="wadl:resources/wadl:resource"> + <xsl:sort select="@path"/> + </xsl:apply-templates> + </div> + </body> + </html> + </xsl:template> + + <xsl:template name="dialog-init"> + <xsl:param name="resourcePath"/> + + <xsl:for-each select="wadl:method"> + <xsl:text>$(function() { + $( "#dialog</xsl:text> + <xsl:value-of select="$resourcePath"/>_<xsl:value-of select="position()"/> + <xsl:text>" ).dialog({ + autoOpen: false, + modal: true, + height: "auto", + width: "auto", + resizable: false + }); + + $( "#opener</xsl:text> + <xsl:value-of select="$resourcePath"/>_<xsl:value-of select="position()"/> + <xsl:text>" ).click(function() { + $( "#dialog</xsl:text> + <xsl:value-of select="$resourcePath"/>_<xsl:value-of select="position()"/> + <xsl:text>" ).dialog( "open" ); + }); + }); + </xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template match="xs:schema"> + <xsl:variable name="targetNamespace" select="@targetNamespace"/> + + <xsl:variable name="prefix" + select="xalan:nodeset($namespaces)/namespace[@url = $targetNamespace]/@prefix"/> + + <tr> + <td> + <xsl:value-of select="$prefix"/> + </td> + <td> + <xsl:value-of select="@targetNamespace"/> + </td> + <td> + <a href="schema_{position()}_{$prefix}.html" + onClick="window.open('', 'schema', '', true).focus();" target="schema"> + <xsl:value-of select="$prefix"/>.xsd</a> + </td> + </tr> + </xsl:template> + + <xsl:template match="wadl:resource"> + <div id="tabs-{position()}"> + <h2> + <xsl:value-of select="@path"/> + </h2> + + <xsl:if test="string-length(wadl:doc) > 0"> + <p> + <xsl:value-of select="wadl:doc/text()" disable-output-escaping="yes"/> + </p> + </xsl:if> + + <xsl:call-template name="parameters"/> + + <xsl:call-template name="methods"> + <xsl:with-param name="resourcePath" select="@path"/> + </xsl:call-template> + + <xsl:variable name="parentPath" select="@path"/> + <div id="accordion-{position()}"> + <xsl:for-each select="descendant::*[local-name() = 'resource']"> + <xsl:sort select="@path"/> + <xsl:call-template name="subresource"> + <xsl:with-param name="parentPath" select="$parentPath"/> + </xsl:call-template> + </xsl:for-each> + </div> + </div> + </xsl:template> + + <xsl:template name="methods"> + <xsl:param name="resourcePath"/> + + <xsl:variable name="escapedPath" select="translate($resourcePath, '/{}', '___')"/> + <div class="methods"> + <xsl:for-each select="wadl:method"> + <button id="opener{$escapedPath}_{position()}"> + <xsl:value-of select="@name"/> + <xsl:if test="string-length(@id) > 0"> + <br/> + (<em> + <xsl:value-of select="@id"/> + </em>) + </xsl:if> + </button> + <div id="dialog{$escapedPath}_{position()}" title="{@name} {$resourcePath}"> + <xsl:apply-templates select="."/> + </div> + </xsl:for-each> + </div> + </xsl:template> + + <xsl:template name="subresource"> + <xsl:param name="parentPath"/> + + <h3> + <xsl:value-of select="@path"/> + </h3> + + <div> + <xsl:if test="string-length(wadl:doc) > 0"> + <p> + <xsl:value-of select="wadl:doc/text()" disable-output-escaping="yes"/> + </p> + </xsl:if> + + <xsl:call-template name="parameters"/> + + <xsl:call-template name="methods"> + <xsl:with-param name="resourcePath" select="concat($parentPath, @path)"/> + </xsl:call-template> + </div> + </xsl:template> + + <xsl:template match="wadl:method"> + <xsl:if test="string-length(wadl:doc) > 0"> + <p> + <xsl:value-of select="wadl:doc/text()" disable-output-escaping="yes"/> + </p> + </xsl:if> + + <xsl:if test="count(wadl:request/@*) + count(wadl:request/*) > 0"> + <xsl:apply-templates select="wadl:request"/> + </xsl:if> + <xsl:if test="count(wadl:response/@*) + count(wadl:response/*) > 0"> + <xsl:apply-templates select="wadl:response"/> + </xsl:if> + </xsl:template> + + <xsl:template match="wadl:request|wadl:response"> + <xsl:call-template name="parameters"/> + + <h4> + R<xsl:value-of select="substring-after(local-name(), 'r')"/> + </h4> + + <xsl:if test="string-length(wadl:doc) > 0"> + <p> + <xsl:value-of select="wadl:doc/text()" disable-output-escaping="yes"/> + </p> + </xsl:if> + + <table> + <xsl:if test="string-length(@status) >0 "> + <tr> + <td class="representation-label">Status</td> + <td> + <xsl:value-of select="@status"/> + </td> + </tr> + </xsl:if> + <xsl:if test="count(wadl:representation) > 0"> + <tr> + <td class="representation-label">Content type</td> + <td> + <xsl:if test="count(wadl:representation/@element) > 0"> + <xsl:choose> + <xsl:when test="starts-with(wadl:representation/@element, 'xs:')"> + <xsl:value-of select="wadl:representation/@element"/> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="schema-prefix" + select="substring-before(wadl:representation/@element, ':')"/> + <xsl:variable name="nsURL" + select="xalan:nodeset($namespaces)/namespace[@prefix = $schema-prefix]/@url"/> + <xsl:variable name="schema-position" + select="xalan:nodeset($namespacePos)/namespace[@url = $nsURL]/@position"/> + + <a href="schema_{$schema-position}_{$schema-prefix}.html#{substring-after(wadl:representation/@element, ':')}" + onClick="window.open('', 'schema', '', true).focus();" target="schema"> + <xsl:value-of select="wadl:representation/@element"/> + </a> + </xsl:otherwise> + </xsl:choose> + </xsl:if> + <xsl:if test="count(wadl:representation/wadl:param) > 0"> + <xsl:value-of select="wadl:representation/wadl:param/@type"/> + </xsl:if> + <xsl:if test="count(wadl:representation/wadl:doc) > 0"> + <br/> + <xsl:value-of select="wadl:representation/wadl:doc/text()" disable-output-escaping="yes"/> + </xsl:if> + </td> + </tr> + <tr> + <td class="representation-label">Media types</td> + <td> + <xsl:for-each select="wadl:representation"> + <xsl:value-of select="@mediaType"/> + <br/> + </xsl:for-each> + </td> + </tr> + </xsl:if> + </table> + </xsl:template> + + <xsl:template name="parameters"> + <xsl:if test="count(wadl:param) > 0"> + <h5>Parameters</h5> + <table> + <tr> + <th>Name</th> + <th>Description</th> + <th>Style</th> + <th>Type</th> + <th>Default</th> + </tr> + <xsl:for-each select="wadl:param"> + <tr> + <td> + <xsl:value-of select="@name"/> + </td> + <td> + <xsl:value-of select="wadl:doc/text()" disable-output-escaping="yes"/> + </td> + <td> + <xsl:value-of select="@style"/> + </td> + <td> + <xsl:value-of select="@type"/> + <xsl:if test="count(wadl:option) > 0"> + <ul> + <xsl:for-each select="wadl:option"> + <li> + <xsl:value-of select="@value"/> + </li> + </xsl:for-each> + </ul> + </xsl:if> + </td> + <td> + <xsl:value-of select="@default"/> + </td> + </tr> + </xsl:for-each> + </table> + </xsl:if> + </xsl:template> + +</xsl:stylesheet> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/rest-cxf/src/main/resources/wadl2html/schema.xsl ---------------------------------------------------------------------- diff --git a/syncope620/core/rest-cxf/src/main/resources/wadl2html/schema.xsl b/syncope620/core/rest-cxf/src/main/resources/wadl2html/schema.xsl new file mode 100644 index 0000000..6551d09 --- /dev/null +++ b/syncope620/core/rest-cxf/src/main/resources/wadl2html/schema.xsl @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:wadl="http://wadl.dev.java.net/2009/02" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + exclude-result-prefixes="wadl xs" + version="1.0"> + + <xsl:strip-space elements="*"/> + + <xsl:param name="contextPath"/> + <xsl:param name="schema-position"/> + <xsl:param name="schema-prefix"/> + + <xsl:template match="/wadl:application"> + <html lang="en"> + <head> + <meta charset="utf-8"/> + <title> + <xsl:value-of select="wadl:doc/@title"/> + </title> + + <link rel="stylesheet" href="{$contextPath}/webjars/highlightjs/${highlightjs.version}/styles/default.min.css"/> + + <script src="{$contextPath}/webjars/highlightjs/${highlightjs.version}/highlight.min.js"> + </script> + <script> + hljs.initHighlightingOnLoad(); + </script> + </head> + <body> + <pre> + <code class="xml"> + <xsl:apply-templates select="//xs:schema[position() = $schema-position]" mode="verb"/> + </code> + </pre> + </body> + </html> + </xsl:template> + + <xsl:template match="*|@*" mode="verb"> + <xsl:variable name="node-type"> + <xsl:call-template name="node-type"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="$node-type='element'"> + <xsl:for-each select="ancestor::node()"> + <xsl:if test="position() > 3"> + <xsl:text>  </xsl:text> + </xsl:if> + </xsl:for-each> + + <xsl:choose> + <xsl:when test="name() = 'xs:complexType' or name() = 'xs:simpleType'"> + <a name="int_{@name}"> + <xsl:text><</xsl:text> + <xsl:value-of select="name()"/> + </a> + </xsl:when> + <xsl:when test="name() = 'xs:element'"> + <a name="{@name}"> + <xsl:text><</xsl:text> + <xsl:value-of select="name()"/> + </a> + </xsl:when> + <xsl:otherwise> + <xsl:text><</xsl:text> + <xsl:value-of select="name()"/> + </xsl:otherwise> + </xsl:choose> + + <xsl:apply-templates select="@*" mode="verb"/> + + <xsl:choose> + <xsl:when test="count(descendant::node()) = 0"> + <xsl:text>/> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>> </xsl:text> + + <xsl:apply-templates mode="verb"/> + + <xsl:for-each select="ancestor::node()"> + <xsl:if test="position() > 3"> + <xsl:text>  </xsl:text> + </xsl:if> + </xsl:for-each> + + <xsl:text></</xsl:text> + <xsl:value-of select="name()"/> + <xsl:text>> </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="$node-type='text'"> + <xsl:value-of select="self::text()"/> + </xsl:when> + <xsl:when test="$node-type='attribute'"> + <xsl:text> </xsl:text> + <xsl:value-of select="name()"/> + <xsl:text>="</xsl:text> + <xsl:choose> + <xsl:when test="contains(., ':') and not(starts-with(., 'xs:'))"> + <a> + <xsl:variable name="current" select="."/> + <xsl:attribute name="href"> + <xsl:choose> + <xsl:when test="name() = 'ref'">#<xsl:value-of select="substring-after($current, ':')"/></xsl:when> + <xsl:otherwise>#int_<xsl:value-of select="substring-after($current, ':')"/></xsl:otherwise> + </xsl:choose> + </xsl:attribute> + <xsl:value-of select="$current"/> + </a> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="."/> + </xsl:otherwise> + </xsl:choose> + <xsl:text>"</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:template> + + <xsl:template name="node-type"> + <xsl:param name="node" select="."/> + <xsl:apply-templates mode="nodetype" select="$node"/> + </xsl:template> + <xsl:template mode="nodetype" match="*">element</xsl:template> + <xsl:template mode="nodetype" match="@*">attribute</xsl:template> + <xsl:template mode="nodetype" match="text()">text</xsl:template> +</xsl:stylesheet> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-activiti/pom.xml ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/pom.xml b/syncope620/core/workflow-activiti/pom.xml new file mode 100644 index 0000000..78dacd6 --- /dev/null +++ b/syncope620/core/workflow-activiti/pom.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.syncope</groupId> + <artifactId>syncope-core</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Core Workflow Activiti</name> + <description>Apache Syncope Core Workflow Activiti</description> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-activiti</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../..</rootpom.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + + <dependency> + <groupId>org.activiti</groupId> + <artifactId>activiti-engine</artifactId> + </dependency> + <dependency> + <groupId>org.activiti</groupId> + <artifactId>activiti-spring</artifactId> + </dependency> + <dependency> + <groupId>org.activiti</groupId> + <artifactId>activiti-json-converter</artifactId> + </dependency> + + <dependency> + <groupId>org.codehaus.groovy</groupId> + <artifactId>groovy-all</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-workflow-java</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-misc</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java b/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java new file mode 100644 index 0000000..6108b2b --- /dev/null +++ b/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiDefinitionLoader.java @@ -0,0 +1,103 @@ +/* + * 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.workflow.activiti; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import javax.annotation.Resource; +import org.activiti.editor.constants.ModelDataJsonConstants; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.repository.Model; +import org.activiti.engine.repository.ProcessDefinition; +import org.activiti.spring.SpringProcessEngineConfiguration; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader; +import org.apache.syncope.core.persistence.api.SyncopeLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ActivitiDefinitionLoader implements SyncopeLoader { + + private static final Logger LOG = LoggerFactory.getLogger(ActivitiDefinitionLoader.class); + + @Resource(name = "userWorkflowDef") + private ResourceWithFallbackLoader userWorkflowDef; + + @Autowired + private RepositoryService repositoryService; + + @Autowired + private SpringProcessEngineConfiguration conf; + + @Autowired + private ActivitiImportUtils importUtils; + + @Override + public Integer getPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void load() { + List<ProcessDefinition> processes = repositoryService.createProcessDefinitionQuery().processDefinitionKey( + ActivitiUserWorkflowAdapter.WF_PROCESS_ID).list(); + LOG.debug(ActivitiUserWorkflowAdapter.WF_PROCESS_ID + " Activiti processes in repository: {}", processes); + + // Only loads process definition from file if not found in repository + if (processes.isEmpty()) { + InputStream wfIn = null; + try { + wfIn = userWorkflowDef.getResource().getInputStream(); + repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, + new ByteArrayInputStream(IOUtils.toByteArray(wfIn))).deploy(); + + ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionKey( + ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult(); + + Model model = repositoryService.newModel(); + ObjectNode modelObjectNode = new ObjectMapper().createObjectNode(); + modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, procDef.getName()); + modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1); + modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, procDef.getDescription()); + model.setMetaInfo(modelObjectNode.toString()); + model.setName(procDef.getName()); + model.setDeploymentId(procDef.getDeploymentId()); + importUtils.fromJSON(procDef, model); + + LOG.debug("Activiti Workflow definition loaded"); + } catch (IOException e) { + LOG.error("While loading " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e); + } finally { + IOUtils.closeQuietly(wfIn); + } + } + + // jump to the next ID block + for (int i = 0; i < conf.getIdBlockSize(); i++) { + conf.getIdGenerator().getNextId(); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java ---------------------------------------------------------------------- diff --git a/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java b/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java new file mode 100644 index 0000000..973584d --- /dev/null +++ b/syncope620/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiImportUtils.java @@ -0,0 +1,92 @@ +/* + * 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.workflow.activiti; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import org.activiti.bpmn.converter.BpmnXMLConverter; +import org.activiti.bpmn.model.BpmnModel; +import org.activiti.editor.language.json.converter.BpmnJsonConverter; +import org.activiti.engine.ActivitiException; +import org.activiti.engine.RepositoryService; +import org.activiti.engine.repository.Model; +import org.activiti.engine.repository.ProcessDefinition; +import org.apache.commons.io.IOUtils; +import org.apache.syncope.core.workflow.api.WorkflowException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ActivitiImportUtils { + + @Autowired + private RepositoryService repositoryService; + + public void fromXML(final byte[] definition) { + try { + repositoryService.createDeployment().addInputStream(ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, + new ByteArrayInputStream(definition)).deploy(); + } catch (ActivitiException e) { + throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e); + } + } + + public void fromJSON(final byte[] definition, final ProcessDefinition procDef, final Model model) { + try { + model.setVersion(procDef.getVersion()); + model.setDeploymentId(procDef.getDeploymentId()); + repositoryService.saveModel(model); + + repositoryService.addModelEditorSource(model.getId(), definition); + } catch (Exception e) { + throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e); + } + } + + public void fromJSON(final ProcessDefinition procDef, final Model model) { + InputStream bpmnStream = null; + InputStreamReader isr = null; + XMLStreamReader xtr = null; + try { + bpmnStream = repositoryService.getResourceAsStream( + procDef.getDeploymentId(), procDef.getResourceName()); + isr = new InputStreamReader(bpmnStream); + xtr = XMLInputFactory.newInstance().createXMLStreamReader(isr); + BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr); + + fromJSON(new BpmnJsonConverter().convertToJson(bpmnModel).toString().getBytes(), procDef, model); + } catch (Exception e) { + throw new WorkflowException("While updating process " + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e); + } finally { + if (xtr != null) { + try { + xtr.close(); + } catch (XMLStreamException e) { + // ignore + } + } + IOUtils.closeQuietly(isr); + IOUtils.closeQuietly(bpmnStream); + } + } +}
