You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/11/25 12:26:04 UTC
[1/5] syncope git commit: Upgrading Activiti
Repository: syncope
Updated Branches:
refs/heads/master 7b1cb89bb -> e9ff5c73e
Upgrading Activiti
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/560fc4df
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/560fc4df
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/560fc4df
Branch: refs/heads/master
Commit: 560fc4df106825c80520f941beb2e0e601cb056f
Parents: 1bee9d7
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 18 14:54:17 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 18 14:54:17 2015 +0100
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/560fc4df/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5e6921b..fc8a0b6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -339,7 +339,7 @@ under the License.
<commons-lang.version>3.3.2</commons-lang.version>
<commons-codec.version>1.10</commons-codec.version>
- <activiti.version>5.16.4</activiti.version>
+ <activiti.version>5.16.5</activiti.version>
<aspectj.version>1.8.7</aspectj.version>
[4/5] syncope git commit: Cleaning up invalid AnyObjectService#list
(with no params) method, and adjusting CLI accordingly
Posted by il...@apache.org.
Cleaning up invalid AnyObjectService#list (with no params) method, and adjusting CLI accordingly
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0f938e72
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0f938e72
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0f938e72
Branch: refs/heads/master
Commit: 0f938e72d6723517fe451010ec3a2e398b3e4ecc
Parents: bbb051f
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 25 12:07:53 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 25 12:09:02 2015 +0100
----------------------------------------------------------------------
.../cli/commands/any/AbstractAnyCommand.java | 27 -----
.../client/cli/commands/any/AnyCommand.java | 111 -------------------
.../client/cli/commands/any/AnyDelete.java | 59 ----------
.../client/cli/commands/any/AnyList.java | 50 ---------
.../client/cli/commands/any/AnyRead.java | 58 ----------
...yReadAttributeBySchemaTypeAndSchemaName.java | 61 ----------
.../any/AnyReadAttributesBySchemaType.java | 64 -----------
.../cli/commands/any/AnyResultManager.java | 80 -------------
.../cli/commands/any/AnySyncopeOperations.java | 53 ---------
.../anyobject/AbstractAnyObjectCommand.java | 27 +++++
.../commands/anyobject/AnyObjectCommand.java | 111 +++++++++++++++++++
.../cli/commands/anyobject/AnyObjectDelete.java | 59 ++++++++++
.../cli/commands/anyobject/AnyObjectList.java | 50 +++++++++
.../cli/commands/anyobject/AnyObjectRead.java | 58 ++++++++++
...tReadAttributeBySchemaTypeAndSchemaName.java | 61 ++++++++++
.../AnyObjectReadAttributesBySchemaType.java | 64 +++++++++++
.../anyobject/AnyObjectResultManager.java | 80 +++++++++++++
.../anyobject/AnyObjectSyncopeOperations.java | 53 +++++++++
.../common/rest/api/service/AnyService.java | 11 --
.../common/rest/api/service/GroupService.java | 13 +++
.../common/rest/api/service/UserService.java | 14 +++
.../rest/cxf/service/AbstractAnyService.java | 11 +-
.../core/rest/cxf/service/GroupServiceImpl.java | 7 ++
.../core/rest/cxf/service/UserServiceImpl.java | 7 ++
24 files changed, 609 insertions(+), 580 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AbstractAnyCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AbstractAnyCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AbstractAnyCommand.java
deleted file mode 100644
index dc62ba9..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AbstractAnyCommand.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-public abstract class AbstractAnyCommand {
-
- protected final AnySyncopeOperations anySyncopeOperations = new AnySyncopeOperations();
-
- protected final AnyResultManager anyResultManager = new AnyResultManager();
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyCommand.java
deleted file mode 100644
index c4b2159..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyCommand.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.cli.Command;
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.client.cli.commands.AbstractCommand;
-
-@Command(name = "any")
-public class AnyCommand extends AbstractCommand {
-
- private final AnyResultManager anyResultManager = new AnyResultManager();
-
- @Override
- public void execute(final Input input) {
- if (StringUtils.isBlank(input.getOption())) {
- input.setOption(AnyOptions.HELP.getOptionName());
- }
- switch (AnyOptions.fromName(input.getOption())) {
- case DETAILS:
- break;
- case LIST:
- new AnyList(input).list();
- break;
- case READ:
- new AnyRead(input).read();
- break;
- case READ_ATTRIBUTES_BY_SCHEMA:
- new AnyReadAttributeBySchemaTypeAndSchemaName(input).read();
- break;
- case READ_ATTRIBUTES_BY_SCHEMA_TYPE:
- new AnyReadAttributesBySchemaType(input).read();
- break;
- case DELETE:
- new AnyDelete(input).delete();
- break;
- case HELP:
- System.out.println(getHelpMessage());
- break;
- default:
- anyResultManager.defaultOptionMessage(input.getOption(), getHelpMessage());
- }
- }
-
- @Override
- public String getHelpMessage() {
- return anyResultManager.commandHelpMessage(getClass());
- }
-
- private enum AnyOptions {
-
- HELP("--help"),
- DETAILS("--details"),
- LIST("--list"),
- READ("--read"),
- READ_ATTRIBUTES_BY_SCHEMA("--read-attr-by-schema"),
- READ_ATTRIBUTES_BY_SCHEMA_TYPE("--read-attr-by-schema-type"),
- DELETE("--delete");
-
- private final String optionName;
-
- AnyOptions(final String optionName) {
- this.optionName = optionName;
- }
-
- public String getOptionName() {
- return optionName;
- }
-
- public boolean equalsOptionName(final String otherName) {
- return (otherName == null) ? false : optionName.equals(otherName);
- }
-
- public static AnyOptions fromName(final String name) {
- AnyOptions optionToReturn = HELP;
- for (final AnyOptions option : AnyOptions.values()) {
- if (option.equalsOptionName(name)) {
- optionToReturn = option;
- }
- }
- return optionToReturn;
- }
-
- public static List<String> toList() {
- final List<String> options = new ArrayList<>();
- for (final AnyOptions value : values()) {
- options.add(value.getOptionName());
- }
- return options;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyDelete.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyDelete.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyDelete.java
deleted file mode 100644
index 170cb57..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyDelete.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AnyDelete extends AbstractAnyCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnyDelete.class);
-
- private static final String DELETE_HELP_MESSAGE = "any --delete {ANY-ID} {ANY-ID} [...]";
-
- private final Input input;
-
- public AnyDelete(final Input input) {
- this.input = input;
- }
-
- public void delete() {
- if (input.parameterNumber() >= 1) {
- for (final String parameter : input.getParameters()) {
- try {
- anySyncopeOperations.delete(parameter);
- anyResultManager.deletedMessage("Any", parameter);
- } catch (final SyncopeClientException ex) {
- LOG.error("Error deleting group", ex);
- if (ex.getMessage().startsWith("NotFound")) {
- anyResultManager.notFoundError("any", parameter);
- } else {
- anyResultManager.genericError(ex.getMessage());
- }
- } catch (final NumberFormatException ex) {
- anyResultManager.numberFormatException("any", parameter);
- }
- }
- } else {
- anyResultManager.commandOptionError(DELETE_HELP_MESSAGE);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyList.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyList.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyList.java
deleted file mode 100644
index 5b2ee56..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyList.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AnyList extends AbstractAnyCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnyList.class);
-
- private static final String LIST_HELP_MESSAGE = "any --list";
-
- private final Input input;
-
- public AnyList(final Input input) {
- this.input = input;
- }
-
- public void list() {
- if (input.parameterNumber() == 0) {
- try {
- anyResultManager.printAnys(anySyncopeOperations.list());
- } catch (final SyncopeClientException ex) {
- LOG.error("Error listing any object", ex);
- anyResultManager.genericError(ex.getMessage());
- }
- } else {
- anyResultManager.unnecessaryParameters(input.listParameters(), LIST_HELP_MESSAGE);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyRead.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyRead.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyRead.java
deleted file mode 100644
index ca50b91..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyRead.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AnyRead extends AbstractAnyCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnyRead.class);
-
- private static final String READ_HELP_MESSAGE = "any --read {ANY-ID} {ANY-ID} [...]";
-
- private final Input input;
-
- public AnyRead(final Input input) {
- this.input = input;
- }
-
- public void read() {
- if (input.parameterNumber() >= 1) {
- for (final String parameter : input.getParameters()) {
- try {
- anyResultManager.printGroup(anySyncopeOperations.read(parameter));
- } catch (final SyncopeClientException ex) {
- LOG.error("Error reading group", ex);
- if (ex.getMessage().startsWith("NotFound")) {
- anyResultManager.notFoundError("Any object", parameter);
- } else {
- anyResultManager.genericError(ex.getMessage());
- }
- } catch (final NumberFormatException ex) {
- anyResultManager.numberFormatException("any object", parameter);
- }
- }
- } else {
- anyResultManager.commandOptionError(READ_HELP_MESSAGE);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributeBySchemaTypeAndSchemaName.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributeBySchemaTypeAndSchemaName.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributeBySchemaTypeAndSchemaName.java
deleted file mode 100644
index b1cd414..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributeBySchemaTypeAndSchemaName.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.client.cli.util.CommandUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AnyReadAttributeBySchemaTypeAndSchemaName extends AbstractAnyCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnyReadAttributeBySchemaTypeAndSchemaName.class);
-
- private static final String READ_HELP_MESSAGE
- = "any --read-attr-by-schema {ANY-ID} {SCHEMA-TYPE} {SCHEMA-NAME}\n"
- + " Schema type: PLAIN / DERIVED / VIRTUAL";
-
- private final Input input;
-
- public AnyReadAttributeBySchemaTypeAndSchemaName(final Input input) {
- this.input = input;
- }
-
- public void read() {
- if (input.parameterNumber() == 3) {
- try {
- anyResultManager.printAttribute(anySyncopeOperations.readAttribute(
- input.firstParameter(), input.secondParameter(), input.thirdParameter()));
- } catch (final SyncopeClientException ex) {
- LOG.error("Error reading any object", ex);
- anyResultManager.genericError(ex.getMessage());
- } catch (final NumberFormatException ex) {
- anyResultManager.numberFormatException("any object", input.firstParameter());
- } catch (final IllegalArgumentException ex) {
- LOG.error("Error reading schema", ex);
- anyResultManager.typeNotValidError(
- "schema", input.secondParameter(), CommandUtils.fromEnumToArray(SchemaType.class));
- }
- } else {
- anyResultManager.commandOptionError(READ_HELP_MESSAGE);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributesBySchemaType.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributesBySchemaType.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributesBySchemaType.java
deleted file mode 100644
index 602c68f..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyReadAttributesBySchemaType.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.client.cli.util.CommandUtils;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AnyReadAttributesBySchemaType extends AbstractAnyCommand {
-
- private static final Logger LOG = LoggerFactory.getLogger(AnyReadAttributesBySchemaType.class);
-
- private static final String READ_HELP_MESSAGE = "any --read-attr-by-schema-type {ANY-ID} {SCHEMA-TYPE}\n"
- + " Schema type: PLAIN / DERIVED / VIRTUAL";
-
- private final Input input;
-
- public AnyReadAttributesBySchemaType(final Input input) {
- this.input = input;
- }
-
- public void read() {
- if (input.parameterNumber() == 2) {
- try {
- anyResultManager.printAttributes(anySyncopeOperations.readAttributes(
- input.firstParameter(), input.secondParameter()));
- } catch (final SyncopeClientException ex) {
- LOG.error("Error reading any", ex);
- if (ex.getMessage().startsWith("NotFound")) {
- anyResultManager.notFoundError("Any", input.firstParameter());
- } else {
- anyResultManager.genericError(ex.getMessage());
- }
- } catch (final NumberFormatException ex) {
- anyResultManager.numberFormatException("any", input.firstParameter());
- } catch (final IllegalArgumentException ex) {
- LOG.error("Error reading schema", ex);
- anyResultManager.typeNotValidError(
- "schema", input.secondParameter(), CommandUtils.fromEnumToArray(SchemaType.class));
- }
- } else {
- anyResultManager.commandOptionError(READ_HELP_MESSAGE);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyResultManager.java
deleted file mode 100644
index 3b50406..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnyResultManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.apache.syncope.client.cli.commands.CommonsResultManager;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-
-public class AnyResultManager extends CommonsResultManager {
-
- public void printAnys(final List<AnyObjectTO> anyObjectTOs) {
- System.out.println("");
- for (final AnyObjectTO anyObjectTO : anyObjectTOs) {
- printGroup(anyObjectTO);
- }
- }
-
- public void printGroup(final AnyObjectTO anyObjectTO) {
- System.out.println(" > ANY ID: " + anyObjectTO.getKey());
- System.out.println(" type: " + anyObjectTO.getType());
- System.out.println(" realm: " + anyObjectTO.getRealm());
- System.out.println(" status: " + anyObjectTO.getStatus());
- System.out.println(" RESOURCES: ");
- printResources(anyObjectTO.getResources());
- System.out.println(" PLAIN ATTRIBUTES: ");
- printAttributes(anyObjectTO.getPlainAttrs());
- System.out.println(" DERIVED ATTRIBUTES: ");
- printAttributes(anyObjectTO.getDerAttrs());
- System.out.println(" VIRTUAL ATTRIBUTES: ");
- printAttributes(anyObjectTO.getVirAttrs());
- }
-
- private void printResources(final Set<String> resources) {
- for (final String resource : resources) {
- System.out.println(" - " + resource);
- }
- }
-
- public void printAttributes(final Set<AttrTO> attributes) {
- for (final AttrTO attribute : attributes) {
- printAttribute(attribute);
- }
- System.out.println("");
- }
-
- public void printAttribute(final AttrTO attribute) {
- final StringBuilder attributeMessageBuilder = new StringBuilder();
- attributeMessageBuilder.append(" - ")
- .append(attribute.getSchema())
- .append(": ")
- .append(attribute.getValues());
- if (attribute.isReadonly()) {
- attributeMessageBuilder.append(" - is readonly");
- }
- System.out.println(attributeMessageBuilder.toString());
- }
-
- public void printDetails(final Map<String, String> details) {
- printDetails("groups details", details);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnySyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnySyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnySyncopeOperations.java
deleted file mode 100644
index 5156952..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/any/AnySyncopeOperations.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.client.cli.commands.any;
-
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.client.cli.SyncopeServices;
-import org.apache.syncope.common.lib.to.AnyObjectTO;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.service.AnyObjectService;
-
-public class AnySyncopeOperations {
-
- private final AnyObjectService anyObjectService = SyncopeServices.get(AnyObjectService.class);
-
- public List<AnyObjectTO> list() {
- return anyObjectService.list(new AnyListQuery()).getResult();
- }
-
- public AnyObjectTO read(final String anyId) {
- return anyObjectService.read(Long.valueOf(anyId));
- }
-
- public Set<AttrTO> readAttributes(final String anyId, final String schemaType) {
- return anyObjectService.read(Long.valueOf(anyId), SchemaType.valueOf(schemaType));
- }
-
- public AttrTO readAttribute(final String anyId, final String schemaType, final String schema) {
- return anyObjectService.read(Long.valueOf(anyId), SchemaType.valueOf(schemaType), schema);
- }
-
- public void delete(final String anyId) {
- anyObjectService.delete(Long.valueOf(anyId));
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AbstractAnyObjectCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AbstractAnyObjectCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AbstractAnyObjectCommand.java
new file mode 100644
index 0000000..b78b772
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AbstractAnyObjectCommand.java
@@ -0,0 +1,27 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+public abstract class AbstractAnyObjectCommand {
+
+ protected final AnyObjectSyncopeOperations anySyncopeOperations = new AnyObjectSyncopeOperations();
+
+ protected final AnyObjectResultManager anyResultManager = new AnyObjectResultManager();
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectCommand.java
new file mode 100644
index 0000000..6dc6ba7
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectCommand.java
@@ -0,0 +1,111 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.commands.AbstractCommand;
+
+@Command(name = "anyObject")
+public class AnyObjectCommand extends AbstractCommand {
+
+ private final AnyObjectResultManager anyObjectResultManager = new AnyObjectResultManager();
+
+ @Override
+ public void execute(final Input input) {
+ if (StringUtils.isBlank(input.getOption())) {
+ input.setOption(AnyObjectOptions.HELP.getOptionName());
+ }
+ switch (AnyObjectOptions.fromName(input.getOption())) {
+ case DETAILS:
+ break;
+ case LIST:
+ new AnyObjectList(input).list();
+ break;
+ case READ:
+ new AnyObjectRead(input).read();
+ break;
+ case READ_ATTRIBUTES_BY_SCHEMA:
+ new AnyObjectReadAttributeBySchemaTypeAndSchemaName(input).read();
+ break;
+ case READ_ATTRIBUTES_BY_SCHEMA_TYPE:
+ new AnyObjectReadAttributesBySchemaType(input).read();
+ break;
+ case DELETE:
+ new AnyObjectDelete(input).delete();
+ break;
+ case HELP:
+ System.out.println(getHelpMessage());
+ break;
+ default:
+ anyObjectResultManager.defaultOptionMessage(input.getOption(), getHelpMessage());
+ }
+ }
+
+ @Override
+ public String getHelpMessage() {
+ return anyObjectResultManager.commandHelpMessage(getClass());
+ }
+
+ private enum AnyObjectOptions {
+
+ HELP("--help"),
+ DETAILS("--details"),
+ LIST("--list"),
+ READ("--read"),
+ READ_ATTRIBUTES_BY_SCHEMA("--read-attr-by-schema"),
+ READ_ATTRIBUTES_BY_SCHEMA_TYPE("--read-attr-by-schema-type"),
+ DELETE("--delete");
+
+ private final String optionName;
+
+ AnyObjectOptions(final String optionName) {
+ this.optionName = optionName;
+ }
+
+ public String getOptionName() {
+ return optionName;
+ }
+
+ public boolean equalsOptionName(final String otherName) {
+ return (otherName == null) ? false : optionName.equals(otherName);
+ }
+
+ public static AnyObjectOptions fromName(final String name) {
+ AnyObjectOptions optionToReturn = HELP;
+ for (final AnyObjectOptions option : AnyObjectOptions.values()) {
+ if (option.equalsOptionName(name)) {
+ optionToReturn = option;
+ }
+ }
+ return optionToReturn;
+ }
+
+ public static List<String> toList() {
+ final List<String> options = new ArrayList<>();
+ for (final AnyObjectOptions value : values()) {
+ options.add(value.getOptionName());
+ }
+ return options;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectDelete.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectDelete.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectDelete.java
new file mode 100644
index 0000000..16ff80b
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectDelete.java
@@ -0,0 +1,59 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AnyObjectDelete extends AbstractAnyObjectCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnyObjectDelete.class);
+
+ private static final String DELETE_HELP_MESSAGE = "any --delete {ANY-ID} {ANY-ID} [...]";
+
+ private final Input input;
+
+ public AnyObjectDelete(final Input input) {
+ this.input = input;
+ }
+
+ public void delete() {
+ if (input.parameterNumber() >= 1) {
+ for (final String parameter : input.getParameters()) {
+ try {
+ anySyncopeOperations.delete(parameter);
+ anyResultManager.deletedMessage("Any", parameter);
+ } catch (final SyncopeClientException ex) {
+ LOG.error("Error deleting group", ex);
+ if (ex.getMessage().startsWith("NotFound")) {
+ anyResultManager.notFoundError("any", parameter);
+ } else {
+ anyResultManager.genericError(ex.getMessage());
+ }
+ } catch (final NumberFormatException ex) {
+ anyResultManager.numberFormatException("any", parameter);
+ }
+ }
+ } else {
+ anyResultManager.commandOptionError(DELETE_HELP_MESSAGE);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectList.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectList.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectList.java
new file mode 100644
index 0000000..1e3e658
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectList.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.client.cli.commands.anyobject;
+
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AnyObjectList extends AbstractAnyObjectCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnyObjectList.class);
+
+ private static final String LIST_HELP_MESSAGE = "any --list {ANY-TYPE}";
+
+ private final Input input;
+
+ public AnyObjectList(final Input input) {
+ this.input = input;
+ }
+
+ public void list() {
+ if (input.parameterNumber() == 1) {
+ try {
+ anyResultManager.printAnys(anySyncopeOperations.list(input.firstParameter()));
+ } catch (final SyncopeClientException ex) {
+ LOG.error("Error listing any object", ex);
+ anyResultManager.genericError(ex.getMessage());
+ }
+ } else {
+ anyResultManager.unnecessaryParameters(input.listParameters(), LIST_HELP_MESSAGE);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectRead.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectRead.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectRead.java
new file mode 100644
index 0000000..03137f7
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectRead.java
@@ -0,0 +1,58 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AnyObjectRead extends AbstractAnyObjectCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnyObjectRead.class);
+
+ private static final String READ_HELP_MESSAGE = "any --read {ANY-ID} {ANY-ID} [...]";
+
+ private final Input input;
+
+ public AnyObjectRead(final Input input) {
+ this.input = input;
+ }
+
+ public void read() {
+ if (input.parameterNumber() >= 1) {
+ for (final String parameter : input.getParameters()) {
+ try {
+ anyResultManager.printGroup(anySyncopeOperations.read(parameter));
+ } catch (final SyncopeClientException ex) {
+ LOG.error("Error reading group", ex);
+ if (ex.getMessage().startsWith("NotFound")) {
+ anyResultManager.notFoundError("Any object", parameter);
+ } else {
+ anyResultManager.genericError(ex.getMessage());
+ }
+ } catch (final NumberFormatException ex) {
+ anyResultManager.numberFormatException("any object", parameter);
+ }
+ }
+ } else {
+ anyResultManager.commandOptionError(READ_HELP_MESSAGE);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributeBySchemaTypeAndSchemaName.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributeBySchemaTypeAndSchemaName.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributeBySchemaTypeAndSchemaName.java
new file mode 100644
index 0000000..8db0e21
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributeBySchemaTypeAndSchemaName.java
@@ -0,0 +1,61 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.util.CommandUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AnyObjectReadAttributeBySchemaTypeAndSchemaName extends AbstractAnyObjectCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnyObjectReadAttributeBySchemaTypeAndSchemaName.class);
+
+ private static final String READ_HELP_MESSAGE
+ = "any --read-attr-by-schema {ANY-ID} {SCHEMA-TYPE} {SCHEMA-NAME}\n"
+ + " Schema type: PLAIN / DERIVED / VIRTUAL";
+
+ private final Input input;
+
+ public AnyObjectReadAttributeBySchemaTypeAndSchemaName(final Input input) {
+ this.input = input;
+ }
+
+ public void read() {
+ if (input.parameterNumber() == 3) {
+ try {
+ anyResultManager.printAttribute(anySyncopeOperations.readAttribute(
+ input.firstParameter(), input.secondParameter(), input.thirdParameter()));
+ } catch (final SyncopeClientException ex) {
+ LOG.error("Error reading any object", ex);
+ anyResultManager.genericError(ex.getMessage());
+ } catch (final NumberFormatException ex) {
+ anyResultManager.numberFormatException("any object", input.firstParameter());
+ } catch (final IllegalArgumentException ex) {
+ LOG.error("Error reading schema", ex);
+ anyResultManager.typeNotValidError(
+ "schema", input.secondParameter(), CommandUtils.fromEnumToArray(SchemaType.class));
+ }
+ } else {
+ anyResultManager.commandOptionError(READ_HELP_MESSAGE);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributesBySchemaType.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributesBySchemaType.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributesBySchemaType.java
new file mode 100644
index 0000000..ff42b0a
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectReadAttributesBySchemaType.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.client.cli.commands.anyobject;
+
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.util.CommandUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AnyObjectReadAttributesBySchemaType extends AbstractAnyObjectCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AnyObjectReadAttributesBySchemaType.class);
+
+ private static final String READ_HELP_MESSAGE = "any --read-attr-by-schema-type {ANY-ID} {SCHEMA-TYPE}\n"
+ + " Schema type: PLAIN / DERIVED / VIRTUAL";
+
+ private final Input input;
+
+ public AnyObjectReadAttributesBySchemaType(final Input input) {
+ this.input = input;
+ }
+
+ public void read() {
+ if (input.parameterNumber() == 2) {
+ try {
+ anyResultManager.printAttributes(anySyncopeOperations.readAttributes(
+ input.firstParameter(), input.secondParameter()));
+ } catch (final SyncopeClientException ex) {
+ LOG.error("Error reading any", ex);
+ if (ex.getMessage().startsWith("NotFound")) {
+ anyResultManager.notFoundError("Any", input.firstParameter());
+ } else {
+ anyResultManager.genericError(ex.getMessage());
+ }
+ } catch (final NumberFormatException ex) {
+ anyResultManager.numberFormatException("any", input.firstParameter());
+ } catch (final IllegalArgumentException ex) {
+ LOG.error("Error reading schema", ex);
+ anyResultManager.typeNotValidError(
+ "schema", input.secondParameter(), CommandUtils.fromEnumToArray(SchemaType.class));
+ }
+ } else {
+ anyResultManager.commandOptionError(READ_HELP_MESSAGE);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectResultManager.java
new file mode 100644
index 0000000..4f89b23
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectResultManager.java
@@ -0,0 +1,80 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.client.cli.commands.CommonsResultManager;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+
+public class AnyObjectResultManager extends CommonsResultManager {
+
+ public void printAnys(final List<AnyObjectTO> anyObjectTOs) {
+ System.out.println("");
+ for (final AnyObjectTO anyObjectTO : anyObjectTOs) {
+ printGroup(anyObjectTO);
+ }
+ }
+
+ public void printGroup(final AnyObjectTO anyObjectTO) {
+ System.out.println(" > ANY ID: " + anyObjectTO.getKey());
+ System.out.println(" type: " + anyObjectTO.getType());
+ System.out.println(" realm: " + anyObjectTO.getRealm());
+ System.out.println(" status: " + anyObjectTO.getStatus());
+ System.out.println(" RESOURCES: ");
+ printResources(anyObjectTO.getResources());
+ System.out.println(" PLAIN ATTRIBUTES: ");
+ printAttributes(anyObjectTO.getPlainAttrs());
+ System.out.println(" DERIVED ATTRIBUTES: ");
+ printAttributes(anyObjectTO.getDerAttrs());
+ System.out.println(" VIRTUAL ATTRIBUTES: ");
+ printAttributes(anyObjectTO.getVirAttrs());
+ }
+
+ private void printResources(final Set<String> resources) {
+ for (final String resource : resources) {
+ System.out.println(" - " + resource);
+ }
+ }
+
+ public void printAttributes(final Set<AttrTO> attributes) {
+ for (final AttrTO attribute : attributes) {
+ printAttribute(attribute);
+ }
+ System.out.println("");
+ }
+
+ public void printAttribute(final AttrTO attribute) {
+ final StringBuilder attributeMessageBuilder = new StringBuilder();
+ attributeMessageBuilder.append(" - ")
+ .append(attribute.getSchema())
+ .append(": ")
+ .append(attribute.getValues());
+ if (attribute.isReadonly()) {
+ attributeMessageBuilder.append(" - is readonly");
+ }
+ System.out.println(attributeMessageBuilder.toString());
+ }
+
+ public void printDetails(final Map<String, String> details) {
+ printDetails("groups details", details);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectSyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectSyncopeOperations.java
new file mode 100644
index 0000000..c55499a
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/anyobject/AnyObjectSyncopeOperations.java
@@ -0,0 +1,53 @@
+/*
+ * 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.client.cli.commands.anyobject;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.client.cli.SyncopeServices;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+
+public class AnyObjectSyncopeOperations {
+
+ private final AnyObjectService anyObjectService = SyncopeServices.get(AnyObjectService.class);
+
+ public List<AnyObjectTO> list(final String type) {
+ return anyObjectService.list(type, new AnyListQuery()).getResult();
+ }
+
+ public AnyObjectTO read(final String anyId) {
+ return anyObjectService.read(Long.valueOf(anyId));
+ }
+
+ public Set<AttrTO> readAttributes(final String anyId, final String schemaType) {
+ return anyObjectService.read(Long.valueOf(anyId), SchemaType.valueOf(schemaType));
+ }
+
+ public AttrTO readAttribute(final String anyId, final String schemaType, final String schema) {
+ return anyObjectService.read(Long.valueOf(anyId), SchemaType.valueOf(schemaType), schema);
+ }
+
+ public void delete(final String anyId) {
+ anyObjectService.delete(Long.valueOf(anyId));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index ec8495c..1d1bb0f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -41,7 +41,6 @@ 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.types.SchemaType;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
public interface AnyService<TO extends AnyTO, P extends AnyPatch> extends JAXRSService {
@@ -86,16 +85,6 @@ public interface AnyService<TO extends AnyTO, P extends AnyPatch> extends JAXRSS
TO read(@NotNull @PathParam("key") Long key);
/**
- * Returns a paged list of existing any objects matching the given query.
- *
- * @param listQuery query conditions
- * @return paged list of existing any objects matching the given query
- */
- @GET
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- PagedResult<TO> list(@BeanParam AnyListQuery listQuery);
-
- /**
* Returns a paged list of any objects matching the given query.
*
* @param searchQuery query conditions
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
index d1e556d..08535dc 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GroupService.java
@@ -19,12 +19,15 @@
package org.apache.syncope.common.rest.api.service;
import java.util.List;
+import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.common.lib.patch.GroupPatch;
import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
/**
* REST operations for groups.
@@ -42,4 +45,14 @@ public interface GroupService extends AnyService<GroupTO, GroupPatch> {
@Path("own")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
List<GroupTO> own();
+
+ /**
+ * Returns a paged list of existing groups matching the given query.
+ *
+ * @param listQuery query conditions
+ * @return paged list of existing groups matching the given query
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ PagedResult<GroupTO> list(@BeanParam AnyListQuery listQuery);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
index e23e6cd..1fc14f9 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserService.java
@@ -19,8 +19,10 @@
package org.apache.syncope.common.rest.api.service;
import javax.validation.constraints.NotNull;
+import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -31,7 +33,9 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.lib.patch.StatusPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
/**
* REST operations for users.
@@ -60,6 +64,16 @@ public interface UserService extends AnyService<UserTO, UserPatch> {
Response getUserKey(@NotNull @PathParam("username") String username);
/**
+ * Returns a paged list of existing users matching the given query.
+ *
+ * @param listQuery query conditions
+ * @return paged list of existing users matching the given query
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ PagedResult<UserTO> list(@BeanParam AnyListQuery listQuery);
+
+ /**
* Creates a new user.
*
* @param userTO user to be created
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 07dba6e..e08c476 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -109,8 +109,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
return getAnyLogic().read(key);
}
- @Override
- public PagedResult<TO> list(final AnyListQuery listQuery) {
+ protected PagedResult<TO> list(final AnyListQuery listQuery) {
CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
@Override
@@ -260,8 +259,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
for (String resource : patch.getResources()) {
result.getResults().put(resource,
updated.getAny().getResources().contains(resource)
- ? BulkActionResult.Status.FAILURE
- : BulkActionResult.Status.SUCCESS);
+ ? BulkActionResult.Status.FAILURE
+ : BulkActionResult.Status.SUCCESS);
}
} else {
for (PropagationStatus propagationStatusTO : updated.getPropagationStatuses()) {
@@ -317,8 +316,8 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
for (String resource : patch.getResources()) {
result.getResults().put(resource,
updated.getAny().getResources().contains(resource)
- ? BulkActionResult.Status.FAILURE
- : BulkActionResult.Status.SUCCESS);
+ ? BulkActionResult.Status.FAILURE
+ : BulkActionResult.Status.SUCCESS);
}
} else {
for (PropagationStatus propagationStatusTO : updated.getPropagationStatuses()) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index f2915f7..cf65346 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -21,6 +21,8 @@ package org.apache.syncope.core.rest.cxf.service;
import java.util.List;
import org.apache.syncope.common.lib.patch.GroupPatch;
import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
import org.apache.syncope.common.rest.api.service.GroupService;
import org.apache.syncope.core.logic.AbstractAnyLogic;
import org.apache.syncope.core.logic.GroupLogic;
@@ -50,4 +52,9 @@ public class GroupServiceImpl extends AbstractAnyService<GroupTO, GroupPatch> im
return logic.own();
}
+ @Override
+ public PagedResult<GroupTO> list(final AnyListQuery listQuery) {
+ return super.list(listQuery);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/0f938e72/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 0f62925..1b57c38 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -22,9 +22,11 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.lib.patch.StatusPatch;
import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
import org.apache.syncope.common.rest.api.service.UserService;
import org.apache.syncope.core.logic.AbstractAnyLogic;
import org.apache.syncope.core.logic.UserLogic;
@@ -64,6 +66,11 @@ public class UserServiceImpl extends AbstractAnyService<UserTO, UserPatch> imple
}
@Override
+ public PagedResult<UserTO> list(final AnyListQuery listQuery) {
+ return super.list(listQuery);
+ }
+
+ @Override
public Response create(final UserTO userTO, final boolean storePassword) {
ProvisioningResult<UserTO> created = logic.create(userTO, storePassword, isNullPriorityAsync());
return createResponse(created);
[2/5] syncope git commit: [SYNCOPE-119] Added search options and
checks to match assignable conditions,
for usage with memberships and relationships
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index a8ebe0c..639f1b2 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -41,8 +41,11 @@ import org.apache.syncope.common.lib.types.PropagationByResource;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.core.misc.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.RelationshipType;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
@@ -131,52 +134,77 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
- // relationships
- for (RelationshipTO relationshipTO : anyObjectTO.getRelationships()) {
- AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
-
- if (otherEnd == null) {
- LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
- } else {
- RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
- ARelationship relationship = null;
- if (anyObject.getKey() != null) {
- relationship = anyObject.getRelationship(relationshipType, anyObject.getKey());
- }
- if (relationship == null) {
- relationship = entityFactory.newEntity(ARelationship.class);
+ // realm
+ Realm realm = realmDAO.find(anyObjectTO.getRealm());
+ if (realm == null) {
+ SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ noRealm.getElements().add("Invalid or null realm specified: " + anyObjectTO.getRealm());
+ scce.addException(noRealm);
+ }
+ anyObject.setRealm(realm);
+
+ if (anyObject.getRealm() != null) {
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath(anyObject.getRealm().getFullPath());
+
+ // relationships
+ List<AnyObject> assignableAnyObjects =
+ searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.ANY_OBJECT);
+
+ for (RelationshipTO relationshipTO : anyObjectTO.getRelationships()) {
+ AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
+ if (otherEnd == null) {
+ LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+ } else if (assignableAnyObjects.contains(otherEnd)) {
+ RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
+ ARelationship relationship = entityFactory.newEntity(ARelationship.class);
relationship.setType(relationshipType);
relationship.setRightEnd(anyObject);
relationship.setLeftEnd(anyObject);
anyObject.add(relationship);
+ } else {
+ LOG.error("{} cannot be assigned to {}", otherEnd, anyObject);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+ unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+ scce.addException(unassignabled);
}
}
- }
- // memberships
- for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
- Group group = groupDAO.find(membershipTO.getRightKey());
-
- if (group == null) {
- LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
- } else {
- AMembership membership = null;
- if (anyObject.getKey() != null) {
- membership = anyObject.getMembership(group.getKey());
- }
- if (membership == null) {
- membership = entityFactory.newEntity(AMembership.class);
+ // memberships
+ List<Group> assignableGroups =
+ searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.GROUP);
+
+ for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
+ Group group = groupDAO.find(membershipTO.getRightKey());
+ if (group == null) {
+ LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
+ } else if (assignableGroups.contains(group)) {
+ AMembership membership = entityFactory.newEntity(AMembership.class);
membership.setRightEnd(group);
membership.setLeftEnd(anyObject);
anyObject.add(membership);
+ } else {
+ LOG.error("{} cannot be assigned to {}", group, anyObject);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+ unassignabled.getElements().add("Cannot be assigned: " + group);
+ scce.addException(unassignabled);
}
}
}
- // realm, attributes, derived attributes, virtual attributes and resources
+ // attributes, derived attributes, virtual attributes and resources
fill(anyObject, anyObjectTO, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce);
+
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
}
@Override
@@ -200,6 +228,9 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
Set<String> toBeProvisioned = new HashSet<>();
// relationships
+ List<AnyObject> assignableAnyObjects =
+ searchDAO.searchAssignable(anyObject.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT);
+
for (RelationshipPatch patch : anyObjectPatch.getRelationships()) {
if (patch.getRelationshipTO() != null) {
RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
@@ -214,8 +245,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
if (otherEnd == null) {
LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
- } else {
-
+ } else if (assignableAnyObjects.contains(otherEnd)) {
relationship = entityFactory.newEntity(ARelationship.class);
relationship.setType(relationshipType);
relationship.setRightEnd(otherEnd);
@@ -224,12 +254,22 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
anyObject.add(relationship);
toBeProvisioned.addAll(otherEnd.getResourceNames());
+ } else {
+ LOG.error("{} cannot be assigned to {}", otherEnd, anyObject);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+ unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+ scce.addException(unassignabled);
}
}
}
}
// memberships
+ List<Group> assignableGroups =
+ searchDAO.searchAssignable(anyObject.getRealm().getFullPath(), AnyTypeKind.GROUP);
+
for (MembershipPatch patch : anyObjectPatch.getMemberships()) {
if (patch.getMembershipTO() != null) {
AMembership membership = anyObject.getMembership(patch.getMembershipTO().getRightKey());
@@ -242,7 +282,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
Group group = groupDAO.find(patch.getMembershipTO().getRightKey());
if (group == null) {
LOG.debug("Ignoring invalid group {}", patch.getMembershipTO().getRightKey());
- } else {
+ } else if (assignableGroups.contains(group)) {
membership = entityFactory.newEntity(AMembership.class);
membership.setRightEnd(group);
membership.setLeftEnd(anyObject);
@@ -250,6 +290,13 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
anyObject.add(membership);
toBeProvisioned.addAll(group.getResourceNames());
+ } else {
+ LOG.error("{} cannot be assigned to {}", group, anyObject);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+ unassignabled.getElements().add("Cannot be assigned: " + group);
+ scce.addException(unassignabled);
}
}
}
@@ -278,6 +325,11 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
}
}
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
return propByRes;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
index 9562ff7..c71fce5 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -44,6 +44,7 @@ import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
import org.apache.syncope.core.persistence.api.entity.DynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
@@ -85,7 +86,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
}
@Override
- public Group create(final Group group, final GroupTO groupTO) {
+ public void create(final Group group, final GroupTO groupTO) {
SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
// name
@@ -98,7 +99,16 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
group.setName(groupTO.getName());
}
- // realm, attributes, derived attributes, virtual attributes and resources
+ // realm
+ Realm realm = realmDAO.find(groupTO.getRealm());
+ if (realm == null) {
+ SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ noRealm.getElements().add("Invalid or null realm specified: " + groupTO.getRealm());
+ scce.addException(noRealm);
+ }
+ group.setRealm(realm);
+
+ // attributes, derived attributes, virtual attributes and resources
fill(group, groupTO, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce);
// owner
@@ -153,7 +163,10 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
}
}
- return group;
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
}
@Override
@@ -268,6 +281,11 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
}
}
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
return propByRes;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
index ca3448c..22d690a 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/UserDataBinderImpl.java
@@ -57,7 +57,10 @@ import org.apache.syncope.core.misc.security.Encryptor;
import org.apache.syncope.core.misc.spring.BeanUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.RelationshipType;
import org.apache.syncope.core.persistence.api.entity.Role;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
@@ -173,50 +176,71 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
}
}
- // relationships
- for (RelationshipTO relationshipTO : userTO.getRelationships()) {
- AnyObject anyObject = anyObjectDAO.find(relationshipTO.getRightKey());
- if (anyObject == null) {
- LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
- } else {
- RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
- URelationship relationship = null;
- if (user.getKey() != null) {
- relationship = user.getRelationship(relationshipType, anyObject.getKey());
- }
- if (relationship == null) {
- relationship = entityFactory.newEntity(URelationship.class);
+ // realm
+ Realm realm = realmDAO.find(userTO.getRealm());
+ if (realm == null) {
+ SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
+ noRealm.getElements().add("Invalid or null realm specified: " + userTO.getRealm());
+ scce.addException(noRealm);
+ }
+ user.setRealm(realm);
+
+ if (user.getRealm() != null) {
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath(user.getRealm().getFullPath());
+
+ // relationships
+ List<AnyObject> assignableAnyObjects =
+ searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.ANY_OBJECT);
+
+ for (RelationshipTO relationshipTO : userTO.getRelationships()) {
+ AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
+ if (otherEnd == null) {
+ LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+ } else if (assignableAnyObjects.contains(otherEnd)) {
+ RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTO.getType());
+ URelationship relationship = entityFactory.newEntity(URelationship.class);
relationship.setType(relationshipType);
- relationship.setRightEnd(anyObject);
+ relationship.setRightEnd(otherEnd);
relationship.setLeftEnd(user);
user.add(relationship);
+ } else {
+ LOG.error("{} cannot be assigned to {}", otherEnd, user);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+ unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+ scce.addException(unassignabled);
}
}
- }
-
- // memberships
- for (MembershipTO membershipTO : userTO.getMemberships()) {
- Group group = groupDAO.find(membershipTO.getRightKey());
- if (group == null) {
- LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
- } else {
- UMembership membership = null;
- if (user.getKey() != null) {
- membership = user.getMembership(group.getKey());
- }
- if (membership == null) {
- membership = entityFactory.newEntity(UMembership.class);
+ // memberships
+ List<Group> assignableGroups =
+ searchDAO.search(SearchCond.getLeafCond(assignableCond), AnyTypeKind.GROUP);
+
+ for (MembershipTO membershipTO : userTO.getMemberships()) {
+ Group group = groupDAO.find(membershipTO.getRightKey());
+ if (group == null) {
+ LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
+ } else if (assignableGroups.contains(group)) {
+ UMembership membership = entityFactory.newEntity(UMembership.class);
membership.setRightEnd(group);
membership.setLeftEnd(user);
user.add(membership);
+ } else {
+ LOG.error("{} cannot be assigned to {}", group, user);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+ unassignabled.getElements().add("Cannot be assigned: " + group);
+ scce.addException(unassignabled);
}
}
}
- // realm, attributes, derived attributes, virtual attributes and resources
+ // attributes, derived attributes, virtual attributes and resources
fill(user, userTO, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce);
// set password
@@ -239,6 +263,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
user.setSecurityAnswer(userTO.getSecurityAnswer());
user.setMustChangePassword(userTO.isMustChangePassword());
+
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
}
private boolean isPasswordMapped(final ExternalResource resource) {
@@ -341,6 +370,9 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
Set<String> toBeProvisioned = new HashSet<>();
// relationships
+ List<AnyObject> assignableAnyObjects =
+ searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.ANY_OBJECT);
+
for (RelationshipPatch patch : userPatch.getRelationships()) {
if (patch.getRelationshipTO() != null) {
RelationshipType relationshipType = relationshipTypeDAO.find(patch.getRelationshipTO().getType());
@@ -355,7 +387,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
AnyObject otherEnd = anyObjectDAO.find(patch.getRelationshipTO().getRightKey());
if (otherEnd == null) {
LOG.debug("Ignoring invalid any object {}", patch.getRelationshipTO().getRightKey());
- } else {
+ } else if (assignableAnyObjects.contains(otherEnd)) {
relationship = entityFactory.newEntity(URelationship.class);
relationship.setType(relationshipType);
relationship.setRightEnd(otherEnd);
@@ -364,12 +396,22 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
user.add(relationship);
toBeProvisioned.addAll(otherEnd.getResourceNames());
+ } else {
+ LOG.error("{} cannot be assigned to {}", otherEnd, user);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidRelationship);
+ unassignabled.getElements().add("Cannot be assigned: " + otherEnd);
+ scce.addException(unassignabled);
}
}
}
}
// memberships
+ List<Group> assignableGroups =
+ searchDAO.searchAssignable(user.getRealm().getFullPath(), AnyTypeKind.GROUP);
+
for (MembershipPatch patch : userPatch.getMemberships()) {
if (patch.getMembershipTO() != null) {
UMembership membership = user.getMembership(patch.getMembershipTO().getRightKey());
@@ -382,7 +424,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
Group group = groupDAO.find(patch.getMembershipTO().getRightKey());
if (group == null) {
LOG.debug("Ignoring invalid group {}", patch.getMembershipTO().getRightKey());
- } else {
+ } else if (assignableGroups.contains(group)) {
membership = entityFactory.newEntity(UMembership.class);
membership.setRightEnd(group);
membership.setLeftEnd(user);
@@ -403,6 +445,13 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
}
}
}
+ } else {
+ LOG.error("{} cannot be assigned to {}", group, user);
+
+ SyncopeClientException unassignabled =
+ SyncopeClientException.build(ClientExceptionType.InvalidMembership);
+ unassignabled.getElements().add("Cannot be assigned: " + group);
+ scce.addException(unassignabled);
}
}
}
@@ -429,6 +478,11 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
}
}
+ // Throw composite exception if there is at least one element set in the composing exceptions
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
return propByRes;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
index 0be3f0d..82d8647 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
@@ -62,7 +62,7 @@ public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, AnyObj
}
AnySearchQuery searchQuery = new AnySearchQuery();
- searchQuery.setFiql(new AnyObjectFiqlSearchConditionBuilder().type(type).query());
+ searchQuery.setFiql(new AnyObjectFiqlSearchConditionBuilder(type).query());
searchQuery.setDetails(listQuery.isDetails());
searchQuery.setOrderBy(listQuery.getOrderBy());
searchQuery.setPage(listQuery.getPage());
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
index c044187..192fa76 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.patch.AnyObjectPatch;
import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SchemaType;
@@ -68,6 +69,27 @@ public class AnyObjectITCase extends AbstractITCase {
}
@Test
+ public void createInvalidMembership() {
+ // 1. create anyObject in realm /odd and attempt to assign group 15, from realm /even => exception
+ AnyObjectTO anyObjectTO = getSampleTO("createInvalidMembership");
+ anyObjectTO.setRealm("/odd");
+ anyObjectTO.getMemberships().add(new MembershipTO.Builder().group(15L).build());
+
+ try {
+ createAnyObject(anyObjectTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidMembership, e.getType());
+ }
+
+ // 2. change anyObject's realm to /even/two, now it works
+ anyObjectTO.setRealm("/even/two");
+
+ anyObjectTO = createAnyObject(anyObjectTO).getAny();
+ assertTrue(anyObjectTO.getMembershipMap().containsKey(15L));
+ }
+
+ @Test
public void delete() {
try {
anyObjectService.delete(0L);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index 38624b9..d7b8796 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -88,14 +88,14 @@ public class SearchITCase extends AbstractITCase {
@Test
public void searchByGroupNameAndKey() {
- PagedResult<GroupTO> matchingGroups = groupService.search(
+ PagedResult<GroupTO> groups = groupService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
- fiql(SyncopeClient.getUserSearchConditionBuilder().
+ fiql(SyncopeClient.getGroupSearchConditionBuilder().
is("name").equalTo("root").and("key").lessThan(2).query()).build());
- assertNotNull(matchingGroups);
- assertEquals(1, matchingGroups.getResult().size());
- assertEquals("root", matchingGroups.getResult().iterator().next().getName());
- assertEquals(1L, matchingGroups.getResult().iterator().next().getKey());
+ assertNotNull(groups);
+ assertEquals(1, groups.getResult().size());
+ assertEquals("root", groups.getResult().iterator().next().getName());
+ assertEquals(1L, groups.getResult().iterator().next().getKey());
}
@Test
@@ -225,21 +225,21 @@ public class SearchITCase extends AbstractITCase {
@Test
public void searchByBooleanAnyCond() {
- PagedResult<GroupTO> matchingGroups = groupService.search(
+ PagedResult<GroupTO> groups = groupService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
- assertNotNull(matchingGroups);
- assertFalse(matchingGroups.getResult().isEmpty());
+ assertNotNull(groups);
+ assertFalse(groups.getResult().isEmpty());
}
@Test
public void searchByRelationshipAnyCond() {
- PagedResult<GroupTO> matchingGroups = groupService.search(
+ PagedResult<GroupTO> groups = groupService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
- assertNotNull(matchingGroups);
- assertEquals(1, matchingGroups.getResult().size());
- assertEquals(6L, matchingGroups.getResult().iterator().next().getKey());
+ assertNotNull(groups);
+ assertEquals(1, groups.getResult().size());
+ assertEquals(6L, groups.getResult().iterator().next().getKey());
}
@Test
@@ -259,7 +259,7 @@ public class SearchITCase extends AbstractITCase {
public void searchByType() {
PagedResult<AnyObjectTO> matching = anyObjectService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
- fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").query()).build());
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").query()).build());
assertNotNull(matching);
assertFalse(matching.getResult().isEmpty());
@@ -269,13 +269,118 @@ public class SearchITCase extends AbstractITCase {
matching = anyObjectService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
- fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("UNEXISTING").query()).build());
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("UNEXISTING").query()).build());
assertNotNull(matching);
assertTrue(matching.getResult().isEmpty());
}
@Test
+ public void searchByRelationship() {
+ PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+ inRelationships(2L).query()).
+ build());
+ assertNotNull(anyObjects);
+ assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+ @Override
+ public boolean evaluate(final AnyObjectTO anyObject) {
+ return anyObject.getKey() == 1L;
+ }
+ }));
+
+ PagedResult<UserTO> users = userService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationships(1L).query()).
+ build());
+ assertNotNull(users);
+ assertTrue(CollectionUtils.exists(users.getResult(), new Predicate<UserTO>() {
+
+ @Override
+ public boolean evaluate(final UserTO user) {
+ return user.getKey() == 4L;
+ }
+ }));
+ }
+
+ @Test
+ public void searchByRelationshipType() {
+ PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+ inRelationshipTypes("neighborhood").query()).
+ build());
+ assertNotNull(anyObjects);
+ assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+ @Override
+ public boolean evaluate(final AnyObjectTO anyObject) {
+ return anyObject.getKey() == 1L;
+ }
+ }));
+ assertTrue(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+ @Override
+ public boolean evaluate(final AnyObjectTO anyObject) {
+ return anyObject.getKey() == 2L;
+ }
+ }));
+
+ PagedResult<UserTO> users = userService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getUserSearchConditionBuilder().inRelationshipTypes("neighborhood").query()).
+ build());
+ assertNotNull(users);
+ assertTrue(CollectionUtils.exists(users.getResult(), new Predicate<UserTO>() {
+
+ @Override
+ public boolean evaluate(final UserTO user) {
+ return user.getKey() == 4L;
+ }
+ }));
+ }
+
+ @Test
+ public void assignable() {
+ PagedResult<GroupTO> groups = groupService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getGroupSearchConditionBuilder().
+ isAssignable("/even/two").query()).
+ build());
+ assertNotNull(groups);
+ assertTrue(CollectionUtils.exists(groups.getResult(), new Predicate<GroupTO>() {
+
+ @Override
+ public boolean evaluate(final GroupTO group) {
+ return group.getKey() == 15L;
+ }
+ }));
+ assertFalse(CollectionUtils.exists(groups.getResult(), new Predicate<GroupTO>() {
+
+ @Override
+ public boolean evaluate(final GroupTO group) {
+ return group.getKey() == 16L;
+ }
+ }));
+
+ PagedResult<AnyObjectTO> anyObjects = anyObjectService.search(
+ new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
+ isAssignable("/odd").query()).
+ build());
+ assertNotNull(anyObjects);
+ assertFalse(CollectionUtils.exists(anyObjects.getResult(), new Predicate<AnyObjectTO>() {
+
+ @Override
+ public boolean evaluate(final AnyObjectTO anyObject) {
+ return anyObject.getKey() == 3L;
+ }
+ }));
+ }
+
+ @Test
public void orderBy() {
PagedResult<UserTO> matchingUsers = userService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index 75631e7..cea4752 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -416,7 +416,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
// 3. unlink any existing printer and delete from Syncope (printer is now only on external resource)
PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
- fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
is("location").equalTo("sync*").query()).build());
assertTrue(matchingPrinters.getSize() > 0);
for (AnyObjectTO printer : matchingPrinters.getResult()) {
@@ -435,7 +435,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
// hence PrefixMappingItemTransformer was applied during sync)
matchingPrinters = anyObjectService.search(
new AnySearchQuery.Builder().realm(SyncopeConstants.ROOT_REALM).
- fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+ fiql(SyncopeClient.getAnyObjectSearchConditionBuilder("PRINTER").
is("location").equalTo("sync*").query()).build());
assertTrue(matchingPrinters.getSize() > 0);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 54589c6..21adebb 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -445,7 +445,7 @@ public class UserITCase extends AbstractITCase {
@Test
public void createWithRequiredValueMissing() {
- UserTO userTO = getSampleTO("a.b@c.it");
+ UserTO userTO = getUniqueSampleTO("a.b@c.it");
AttrTO type = userTO.getPlainAttrMap().get("type");
userTO.getPlainAttrs().remove(type);
[5/5] syncope git commit: [SYNCOPE-735] Merge from 1_2_X
Posted by il...@apache.org.
[SYNCOPE-735] Merge from 1_2_X
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e9ff5c73
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e9ff5c73
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e9ff5c73
Branch: refs/heads/master
Commit: e9ff5c73ed144337bf9dc44cbb96bbe01ea3e1d7
Parents: 0f938e7 560fc4d
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 25 12:25:46 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 25 12:25:46 2015 +0100
----------------------------------------------------------------------
.../activiti/ActivitiUserWorkflowAdapter.java | 53 ++++++++++++++++++--
.../activiti/spring/DomainProcessEngine.java | 6 +++
2 files changed, 56 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/e9ff5c73/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
----------------------------------------------------------------------
diff --cc core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index 48092ee,0000000..b26c9cd
mode 100644,000000..100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@@ -1,866 -1,0 +1,913 @@@
+/*
+ * 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.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Resource;
+import javax.ws.rs.NotFoundException;
+import org.activiti.bpmn.converter.BpmnXMLConverter;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.editor.constants.ModelDataJsonConstants;
+import org.activiti.editor.language.json.converter.BpmnJsonConverter;
+import org.activiti.engine.ActivitiException;
- import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.form.FormProperty;
+import org.activiti.engine.form.FormType;
+import org.activiti.engine.form.TaskFormData;
+import org.activiti.engine.history.HistoricActivityInstance;
+import org.activiti.engine.history.HistoricDetail;
+import org.activiti.engine.history.HistoricTaskInstance;
+import org.activiti.engine.impl.persistence.entity.HistoricFormPropertyEntity;
+import org.activiti.engine.query.Query;
+import org.activiti.engine.repository.Model;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.patch.PasswordPatch;
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.spring.BeanUtils;
+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.entity.user.User;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
++import org.apache.syncope.core.workflow.activiti.spring.DomainProcessEngine;
+import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
+import org.apache.syncope.core.workflow.api.WorkflowException;
+import org.apache.syncope.core.workflow.java.AbstractUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Activiti {@link http://www.activiti.org/} based implementation.
+ */
+public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
+
+ protected static final String[] PROPERTY_IGNORE_PROPS = { "type" };
+
+ public static final String WF_PROCESS_ID = "userWorkflow";
+
+ public static final String WF_PROCESS_RESOURCE = "userWorkflow.bpmn20.xml";
+
+ public static final String WF_DGRM_RESOURCE = "userWorkflow.userWorkflow.png";
+
+ public static final String USER = "user";
+
+ public static final String WF_EXECUTOR = "wfExecutor";
+
+ public static final String FORM_SUBMITTER = "formSubmitter";
+
+ public static final String USER_TO = "userTO";
+
+ public static final String ENABLED = "enabled";
+
+ public static final String USER_PATCH = "userPatch";
+
+ public static final String EMAIL_KIND = "emailKind";
+
+ public static final String TASK = "task";
+
+ public static final String TOKEN = "token";
+
+ public static final String PASSWORD = "password";
+
+ public static final String PROP_BY_RESOURCE = "propByResource";
+
+ public static final String PROPAGATE_ENABLE = "propagateEnable";
+
+ public static final String ENCRYPTED_PWD = "encryptedPwd";
+
+ public static final String TASK_IS_FORM = "taskIsForm";
+
+ public static final String MODEL_DATA_JSON_MODEL = "model";
+
+ public static final String STORE_PASSWORD = "storePassword";
+
+ public static final String EVENT = "event";
+
+ @Resource(name = "adminUser")
+ protected String adminUser;
+
+ @Autowired
- protected ProcessEngine engine;
++ protected DomainProcessEngine engine;
+
+ @Autowired
+ protected UserDataBinder userDataBinder;
+
+ @Override
+ public String getPrefix() {
+ return "ACT_";
+ }
+
+ protected void throwException(final ActivitiException e, final String defaultMessage) {
+ if (e.getCause() != null) {
+ if (e.getCause().getCause() instanceof SyncopeClientException) {
+ throw (SyncopeClientException) e.getCause().getCause();
+ } else if (e.getCause().getCause() instanceof ParsingValidationException) {
+ throw (ParsingValidationException) e.getCause().getCause();
+ } else if (e.getCause().getCause() instanceof InvalidEntityException) {
+ throw (InvalidEntityException) e.getCause().getCause();
+ }
+ }
+
+ throw new WorkflowException(defaultMessage, e);
+ }
+
+ protected void updateStatus(final User user) {
+ List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+ if (tasks.isEmpty() || tasks.size() > 1) {
+ LOG.warn("While setting user status: unexpected task number ({})", tasks.size());
+ } else {
+ user.setStatus(tasks.get(0).getTaskDefinitionKey());
+ }
+ }
+
+ protected String getFormTask(final User user) {
+ String result = null;
+
+ List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+ if (tasks.isEmpty() || tasks.size() > 1) {
+ LOG.warn("While checking if form task: unexpected task number ({})", tasks.size());
+ } else {
+ try {
+ TaskFormData formData = engine.getFormService().getTaskFormData(tasks.get(0).getId());
+ if (formData != null && !formData.getFormProperties().isEmpty()) {
+ result = tasks.get(0).getId();
+ }
+ } catch (ActivitiException e) {
+ LOG.warn("Could not get task form data", e);
+ }
+ }
+
+ return result;
+ }
+
+ protected Set<String> getPerformedTasks(final User user) {
+ final Set<String> result = new HashSet<>();
+
+ for (HistoricActivityInstance task : engine.getHistoryService().createHistoricActivityInstanceQuery().
+ executionId(user.getWorkflowId()).list()) {
+
+ result.add(task.getActivityId());
+ }
+
+ return result;
+ }
+
++ protected void cleanupHistory(final User user) {
++ JdbcTemplate jdbcTemplate = new JdbcTemplate(engine.getDataSource());
++
++ List<String> taskIds = jdbcTemplate.queryForList(
++ "SELECT TASK_ID_ FROM ACT_HI_VARINST WHERE NAME_='" + TASK_IS_FORM
++ + "' AND LONG_=1 AND PROC_INST_ID_='" + user.getWorkflowId() + "'", String.class);
++
++ StringBuilder update = new StringBuilder();
++
++ update.append("DELETE FROM ACT_HI_VARINST WHERE PROC_INST_ID_='").append(user.getWorkflowId()).append("' ");
++ for (String taskId : taskIds) {
++ update.append("AND TASK_ID_<>'").append(taskId).append("' ");
++ }
++ jdbcTemplate.execute(update.toString());
++
++ update.setLength(0);
++ update.append("DELETE FROM ACT_HI_TASKINST WHERE PROC_INST_ID_='").append(user.getWorkflowId()).append("' ");
++ for (String taskId : taskIds) {
++ update.append("AND ID_<>'").append(taskId).append("' ");
++ }
++ jdbcTemplate.execute(update.toString());
++
++ update.setLength(0);
++ update.append("DELETE FROM ACT_HI_ACTINST WHERE PROC_INST_ID_='").append(user.getWorkflowId()).append("' ");
++ for (String taskId : taskIds) {
++ update.append("AND TASK_ID_<>'").append(taskId).append("' ");
++ }
++ jdbcTemplate.execute(update.toString());
++ }
++
+ /**
+ * Saves resources to be propagated and password for later - after form submission - propagation.
++ *
++ * @param user user
++ * @param password pasword
++ * @param propByRes current propagation actions against resources
+ */
+ protected void saveForFormSubmit(final User user, final String password, final PropagationByResource propByRes) {
+ String formTaskId = getFormTask(user);
+ if (formTaskId != null) {
+ // SYNCOPE-238: This is needed to simplify the task query in this.getForms()
+ engine.getTaskService().setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE);
+ engine.getRuntimeService().setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes);
+ if (propByRes != null) {
+ propByRes.clear();
+ }
+
+ if (StringUtils.isNotBlank(password)) {
+ engine.getRuntimeService().setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password));
+ }
+ }
+ }
+
+ @Override
+ public WorkflowResult<Pair<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
+ final boolean storePassword) {
+
+ return create(userTO, disablePwdPolicyCheck, null, storePassword);
+ }
+
+ @Override
+ public WorkflowResult<Pair<Long, Boolean>> create(final UserTO userTO, final boolean storePassword) {
+ return create(userTO, false, storePassword);
+ }
+
+ @Override
+ public WorkflowResult<Pair<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
+ final Boolean enabled, final boolean storePassword) {
+
+ Map<String, Object> variables = new HashMap<>();
+ variables.put(WF_EXECUTOR, AuthContextUtils.getUsername());
+ variables.put(USER_TO, userTO);
+ variables.put(ENABLED, enabled);
+ variables.put(STORE_PASSWORD, storePassword);
+
+ ProcessInstance processInstance = null;
+ try {
+ processInstance = engine.getRuntimeService().startProcessInstanceByKey(WF_PROCESS_ID, variables);
+ } catch (ActivitiException e) {
+ throwException(e, "While starting " + WF_PROCESS_ID + " instance");
+ }
+
+ User user = engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+
+ Boolean updatedEnabled =
+ engine.getRuntimeService().getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);
+ if (updatedEnabled != null) {
+ user.setSuspended(!updatedEnabled);
+ }
+
+ // this will make UserValidator not to consider password policies at all
+ if (disablePwdPolicyCheck) {
+ user.removeClearPassword();
+ }
+
+ updateStatus(user);
+ user = userDAO.save(user);
+
+ Boolean propagateEnable = engine.getRuntimeService().getVariable(
+ processInstance.getProcessInstanceId(), PROPAGATE_ENABLE, Boolean.class);
+ if (propagateEnable == null) {
+ propagateEnable = enabled;
+ }
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.set(ResourceOperation.CREATE, userDAO.findAllResourceNames(user));
+
+ saveForFormSubmit(user, userTO.getPassword(), propByRes);
+
++ Set<String> tasks = getPerformedTasks(user);
++
++ cleanupHistory(user);
++
+ return new WorkflowResult<Pair<Long, Boolean>>(
- new ImmutablePair<>(user.getKey(), propagateEnable), propByRes, getPerformedTasks(user));
++ new ImmutablePair<>(user.getKey(), propagateEnable), propByRes, tasks);
+ }
+
+ protected Set<String> doExecuteTask(final User user, final String task, final Map<String, Object> moreVariables) {
+ Set<String> preTasks = getPerformedTasks(user);
+
+ Map<String, Object> variables = new HashMap<>();
+ variables.put(WF_EXECUTOR, AuthContextUtils.getUsername());
+ variables.put(TASK, task);
+
+ // using BeanUtils to access all user's properties and trigger lazy loading - we are about to
+ // serialize a User instance for availability within workflow tasks, and this breaks transactions
+ BeanUtils.copyProperties(user, entityFactory.newEntity(User.class));
+ variables.put(USER, user);
+
+ if (moreVariables != null && !moreVariables.isEmpty()) {
+ variables.putAll(moreVariables);
+ }
+
+ if (StringUtils.isBlank(user.getWorkflowId())) {
+ throw new WorkflowException(new NotFoundException("Empty workflow id for " + user));
+ }
+
+ List<Task> tasks = engine.getTaskService().createTaskQuery().processInstanceId(user.getWorkflowId()).list();
+ if (tasks.size() == 1) {
+ try {
+ engine.getTaskService().complete(tasks.get(0).getId(), variables);
+ } catch (ActivitiException e) {
+ throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user);
+ }
+ } else {
+ LOG.warn("Expected a single task, found {}", tasks.size());
+ }
+
+ Set<String> postTasks = getPerformedTasks(user);
+ postTasks.removeAll(preTasks);
+ postTasks.add(task);
++
++ cleanupHistory(user);
++
+ return postTasks;
+ }
+
+ @Override
+ protected WorkflowResult<Long> doActivate(final User user, final String token) {
+ Set<String> tasks = doExecuteTask(user, "activate", Collections.singletonMap(TOKEN, (Object) token));
+
+ updateStatus(user);
+ User updated = userDAO.save(user);
+
+ return new WorkflowResult<>(updated.getKey(), null, tasks);
+ }
+
+ @Override
+ protected WorkflowResult<Pair<UserPatch, Boolean>> doUpdate(final User user, final UserPatch userPatch) {
+ Set<String> tasks = doExecuteTask(user, "update", Collections.singletonMap(USER_PATCH, (Object) userPatch));
+
+ updateStatus(user);
+ User updated = userDAO.save(user);
+
+ PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+ UserPatch updatedPatch = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), USER_PATCH, UserPatch.class);
+
+ saveForFormSubmit(
+ updated, updatedPatch.getPassword() == null ? null : updatedPatch.getPassword().getValue(), propByRes);
+
+ Boolean propagateEnable = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
+
+ return new WorkflowResult<Pair<UserPatch, Boolean>>(
+ new ImmutablePair<>(updatedPatch, propagateEnable), propByRes, tasks);
+ }
+
+ @Override
+ protected WorkflowResult<Long> doSuspend(final User user) {
+ Set<String> performedTasks = doExecuteTask(user, "suspend", null);
+ updateStatus(user);
+ User updated = userDAO.save(user);
+
+ return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+ }
+
+ @Override
+ protected WorkflowResult<Long> doReactivate(final User user) {
+ Set<String> performedTasks = doExecuteTask(user, "reactivate", null);
+ updateStatus(user);
+
+ User updated = userDAO.save(user);
+
+ return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+ }
+
+ @Override
+ protected void doRequestPasswordReset(final User user) {
+ Map<String, Object> variables = new HashMap<>(2);
+ variables.put(USER_TO, userDataBinder.getUserTO(user, true));
+ variables.put(EVENT, "requestPasswordReset");
+
+ doExecuteTask(user, "requestPasswordReset", variables);
+ userDAO.save(user);
+ }
+
+ @Override
+ protected WorkflowResult<Pair<UserPatch, Boolean>> doConfirmPasswordReset(
+ final User user, final String token, final String password) {
+
+ Map<String, Object> variables = new HashMap<>(4);
+ variables.put(TOKEN, token);
+ variables.put(PASSWORD, password);
+ variables.put(USER_TO, userDataBinder.getUserTO(user, true));
+ variables.put(EVENT, "confirmPasswordReset");
+
+ Set<String> tasks = doExecuteTask(user, "confirmPasswordReset", variables);
+
+ userDAO.save(user);
+
+ PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+ UserPatch updatedPatch = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), USER_PATCH, UserPatch.class);
+ Boolean propagateEnable = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
+
+ return new WorkflowResult<Pair<UserPatch, Boolean>>(
+ new ImmutablePair<>(updatedPatch, propagateEnable), propByRes, tasks);
+ }
+
+ @Override
+ protected void doDelete(final User user) {
+ doExecuteTask(user, "delete", null);
+
+ PropagationByResource propByRes = new PropagationByResource();
+ propByRes.set(ResourceOperation.DELETE, userDAO.findAllResourceNames(user));
+
+ saveForFormSubmit(user, null, propByRes);
+
+ if (engine.getRuntimeService().createProcessInstanceQuery().
+ processInstanceId(user.getWorkflowId()).active().list().isEmpty()) {
+
+ userDAO.delete(user.getKey());
+
+ if (!engine.getHistoryService().createHistoricProcessInstanceQuery().
+ processInstanceId(user.getWorkflowId()).list().isEmpty()) {
+
+ engine.getHistoryService().deleteHistoricProcessInstance(user.getWorkflowId());
+ }
+ } else {
+ updateStatus(user);
+ userDAO.save(user);
+ }
+ }
+
+ @Override
+ public WorkflowResult<Long> execute(final UserTO userTO, final String taskId) {
+ User user = userDAO.authFind(userTO.getKey());
+
+ final Map<String, Object> variables = new HashMap<>();
+ variables.put(USER_TO, userTO);
+
+ Set<String> performedTasks = doExecuteTask(user, taskId, variables);
+ updateStatus(user);
+ User updated = userDAO.save(user);
+
+ return new WorkflowResult<>(updated.getKey(), null, performedTasks);
+ }
+
+ protected ProcessDefinition getProcessDefinition() {
+ try {
+ return engine.getRepositoryService().createProcessDefinitionQuery().processDefinitionKey(
+ ActivitiUserWorkflowAdapter.WF_PROCESS_ID).latestVersion().singleResult();
+ } catch (ActivitiException e) {
+ throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
+ }
+
+ }
+
+ protected Model getModel(final ProcessDefinition procDef) {
+ try {
+ Model model = engine.getRepositoryService().createModelQuery().
+ deploymentId(procDef.getDeploymentId()).singleResult();
+ if (model == null) {
+ throw new NotFoundException("Could not find Model for deployment " + procDef.getDeploymentId());
+ }
+ return model;
+ } catch (Exception e) {
+ throw new WorkflowException("While accessing process " + ActivitiUserWorkflowAdapter.WF_PROCESS_ID, e);
+ }
+ }
+
+ protected void exportProcessResource(final String resourceName, final OutputStream os) {
+ ProcessDefinition procDef = getProcessDefinition();
+
+ InputStream procDefIS = engine.getRepositoryService().getResourceAsStream(procDef.getDeploymentId(),
+ resourceName);
+ try {
+ IOUtils.copy(procDefIS, os);
+ } catch (IOException e) {
+ LOG.error("While exporting workflow definition {}", procDef.getKey(), e);
+ } finally {
+ IOUtils.closeQuietly(procDefIS);
+ }
+ }
+
+ protected void exportProcessModel(final OutputStream os) {
+ Model model = getModel(getProcessDefinition());
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ ObjectNode modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
+ modelNode.put(ModelDataJsonConstants.MODEL_ID, model.getId());
+ modelNode.replace(MODEL_DATA_JSON_MODEL,
+ objectMapper.readTree(engine.getRepositoryService().getModelEditorSource(model.getId())));
+
+ os.write(modelNode.toString().getBytes());
+ } catch (IOException e) {
+ LOG.error("While exporting workflow definition {}", model.getId(), e);
+ }
+ }
+
+ @Override
+ public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os) {
+ switch (format) {
+ case JSON:
+ exportProcessModel(os);
+ break;
+
+ case XML:
+ default:
+ exportProcessResource(WF_PROCESS_RESOURCE, os);
+ }
+ }
+
+ @Override
+ public void exportDiagram(final OutputStream os) {
+ exportProcessResource(WF_DGRM_RESOURCE, os);
+ }
+
+ @Override
+ public void importDefinition(final WorkflowDefinitionFormat format, final String definition) {
+ Model model = getModel(getProcessDefinition());
+ switch (format) {
+ case JSON:
+ JsonNode definitionNode;
+ try {
+ definitionNode = new ObjectMapper().readTree(definition);
+ if (definitionNode.has(MODEL_DATA_JSON_MODEL)) {
+ definitionNode = definitionNode.get(MODEL_DATA_JSON_MODEL);
+ }
+ if (!definitionNode.has(BpmnJsonConverter.EDITOR_CHILD_SHAPES)) {
+ throw new IllegalArgumentException(
+ "Could not find JSON node " + BpmnJsonConverter.EDITOR_CHILD_SHAPES);
+ }
+
+ BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(definitionNode);
+ ActivitiImportUtils.fromXML(engine, new BpmnXMLConverter().convertToXML(bpmnModel));
+ } catch (Exception e) {
+ throw new WorkflowException("While updating process "
+ + ActivitiUserWorkflowAdapter.WF_PROCESS_RESOURCE, e);
+ }
+
+ ActivitiImportUtils.fromJSON(
+ engine, definitionNode.toString().getBytes(), getProcessDefinition(), model);
+ break;
+
+ case XML:
+ default:
+ ActivitiImportUtils.fromXML(engine, definition.getBytes());
+
+ ActivitiImportUtils.fromJSON(engine, getProcessDefinition(), model);
+ }
+ }
+
+ protected WorkflowFormPropertyType fromActivitiFormType(final FormType activitiFormType) {
+ WorkflowFormPropertyType result = WorkflowFormPropertyType.String;
+
+ if ("string".equals(activitiFormType.getName())) {
+ result = WorkflowFormPropertyType.String;
+ }
+ if ("long".equals(activitiFormType.getName())) {
+ result = WorkflowFormPropertyType.Long;
+ }
+ if ("enum".equals(activitiFormType.getName())) {
+ result = WorkflowFormPropertyType.Enum;
+ }
+ if ("date".equals(activitiFormType.getName())) {
+ result = WorkflowFormPropertyType.Date;
+ }
+ if ("boolean".equals(activitiFormType.getName())) {
+ result = WorkflowFormPropertyType.Boolean;
+ }
+
+ return result;
+ }
+
+ protected WorkflowFormTO getFormTO(final Task task) {
+ return getFormTO(task, engine.getFormService().getTaskFormData(task.getId()));
+ }
+
+ protected WorkflowFormTO getFormTO(final Task task, final TaskFormData fd) {
+ final WorkflowFormTO formTO =
+ getFormTO(task.getProcessInstanceId(), task.getId(), fd.getFormKey(), fd.getFormProperties());
+
+ BeanUtils.copyProperties(task, formTO);
+ return formTO;
+ }
+
+ protected WorkflowFormTO getFormTO(final HistoricTaskInstance task) {
+ final List<HistoricFormPropertyEntity> props = new ArrayList<>();
+
+ for (HistoricDetail historicDetail
+ : engine.getHistoryService().createHistoricDetailQuery().taskId(task.getId()).list()) {
+
+ if (historicDetail instanceof HistoricFormPropertyEntity) {
+ props.add((HistoricFormPropertyEntity) historicDetail);
+ }
+ }
+
+ final WorkflowFormTO formTO = getHistoricFormTO(
+ task.getProcessInstanceId(), task.getId(), task.getFormKey(), props);
+ BeanUtils.copyProperties(task, formTO);
+
+ final HistoricActivityInstance historicActivityInstance = engine.getHistoryService().
+ createHistoricActivityInstanceQuery().
+ executionId(task.getExecutionId()).activityType("userTask").activityName(task.getName()).singleResult();
+
+ if (historicActivityInstance != null) {
+ formTO.setCreateTime(historicActivityInstance.getStartTime());
+ formTO.setDueDate(historicActivityInstance.getEndTime());
+ }
+
+ return formTO;
+ }
+
+ protected WorkflowFormTO getHistoricFormTO(
+ final String processInstanceId,
+ final String taskId,
+ final String formKey,
+ final List<HistoricFormPropertyEntity> props) {
+
+ WorkflowFormTO formTO = new WorkflowFormTO();
+
+ User user = userDAO.findByWorkflowId(processInstanceId);
+ if (user == null) {
+ throw new NotFoundException("User with workflow id " + processInstanceId);
+ }
+ formTO.setUserKey(user.getKey());
+
+ formTO.setTaskId(taskId);
+ formTO.setKey(formKey);
+
+ for (HistoricFormPropertyEntity prop : props) {
+ WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
+ propertyTO.setId(prop.getPropertyId());
+ propertyTO.setName(prop.getPropertyId());
+ propertyTO.setValue(prop.getPropertyValue());
+ formTO.addProperty(propertyTO);
+ }
+
+ return formTO;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected WorkflowFormTO getFormTO(
+ final String processInstanceId,
+ final String taskId,
+ final String formKey,
+ final List<FormProperty> properties) {
+
+ WorkflowFormTO formTO = new WorkflowFormTO();
+
+ User user = userDAO.findByWorkflowId(processInstanceId);
+ if (user == null) {
+ throw new NotFoundException("User with workflow id " + processInstanceId);
+ }
+ formTO.setUserKey(user.getKey());
+
+ formTO.setTaskId(taskId);
+ formTO.setKey(formKey);
+
+ for (FormProperty fProp : properties) {
+ WorkflowFormPropertyTO propertyTO = new WorkflowFormPropertyTO();
+ BeanUtils.copyProperties(fProp, propertyTO, PROPERTY_IGNORE_PROPS);
+ propertyTO.setType(fromActivitiFormType(fProp.getType()));
+
+ if (propertyTO.getType() == WorkflowFormPropertyType.Date) {
+ propertyTO.setDatePattern((String) fProp.getType().getInformation("datePattern"));
+ }
+ if (propertyTO.getType() == WorkflowFormPropertyType.Enum) {
+ propertyTO.getEnumValues().putAll((Map<String, String>) fProp.getType().getInformation("values"));
+ }
+
+ formTO.addProperty(propertyTO);
+ }
+
+ return formTO;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<WorkflowFormTO> getForms() {
+ List<WorkflowFormTO> forms = new ArrayList<>();
+
+ String authUser = AuthContextUtils.getUsername();
+ if (adminUser.equals(authUser)) {
+ forms.addAll(getForms(engine.getTaskService().createTaskQuery().
+ taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
+ } else {
+ User user = userDAO.find(authUser);
+ if (user == null) {
+ throw new NotFoundException("Syncope User " + authUser);
+ }
+
+ forms.addAll(getForms(engine.getTaskService().createTaskQuery().
+ taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
+ taskCandidateOrAssigned(user.getKey().toString())));
+
+ List<String> candidateGroups = new ArrayList<>();
+ for (Long groupId : userDAO.findAllGroupKeys(user)) {
+ candidateGroups.add(groupId.toString());
+ }
+ if (!candidateGroups.isEmpty()) {
+ forms.addAll(getForms(engine.getTaskService().createTaskQuery().
+ taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE).
+ taskCandidateGroupIn(candidateGroups)));
+ }
+ }
+
+ return forms;
+ }
+
+ @Override
+ public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
+ List<WorkflowFormTO> forms = getForms(
+ engine.getTaskService().createTaskQuery().processInstanceId(workflowId).taskName(name).
+ taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE));
+
+ forms.addAll(getForms(engine.getHistoryService().createHistoricTaskInstanceQuery().taskName(name).
+ taskVariableValueEquals(TASK_IS_FORM, Boolean.TRUE)));
+
+ return forms;
+ }
+
+ protected <T extends Query<?, ?>, U extends Object> List<WorkflowFormTO> getForms(final Query<T, U> query) {
+ List<WorkflowFormTO> forms = new ArrayList<>();
+
+ for (U obj : query.list()) {
+ try {
+ if (obj instanceof HistoricTaskInstance) {
+ forms.add(getFormTO((HistoricTaskInstance) obj));
+ } else if (obj instanceof Task) {
+ forms.add(getFormTO((Task) obj));
+ } else {
+ throw new ActivitiException(
+ "Failure retrieving form", new IllegalArgumentException("Invalid task type"));
+ }
+ } catch (ActivitiException e) {
+ LOG.debug("No form found for task {}", obj, e);
+ }
+ }
+
+ return forms;
+ }
+
+ @Override
+ public WorkflowFormTO getForm(final String workflowId) {
+ Task task;
+ try {
+ task = engine.getTaskService().createTaskQuery().processInstanceId(workflowId).singleResult();
+ } catch (ActivitiException e) {
+ throw new WorkflowException("While reading form for workflow instance " + workflowId, e);
+ }
+
+ TaskFormData formData;
+ try {
+ formData = engine.getFormService().getTaskFormData(task.getId());
+ } catch (ActivitiException e) {
+ LOG.debug("No form found for task {}", task.getId(), e);
+ formData = null;
+ }
+
+ WorkflowFormTO result = null;
+ if (formData != null && !formData.getFormProperties().isEmpty()) {
+ result = getFormTO(task);
+ }
+
+ return result;
+ }
+
+ protected Pair<Task, TaskFormData> checkTask(final String taskId, final String authUser) {
+ Task task;
+ try {
+ task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
++ if (task == null) {
++ throw new ActivitiException("NULL result");
++ }
+ } catch (ActivitiException e) {
+ throw new NotFoundException("Activiti Task " + taskId, e);
+ }
+
+ TaskFormData formData;
+ try {
+ formData = engine.getFormService().getTaskFormData(task.getId());
+ } catch (ActivitiException e) {
+ throw new NotFoundException("Form for Activiti Task " + taskId, e);
+ }
+
+ if (!adminUser.equals(authUser)) {
+ User user = userDAO.find(authUser);
+ if (user == null) {
+ throw new NotFoundException("Syncope User " + authUser);
+ }
+ }
+
+ return new ImmutablePair<>(task, formData);
+ }
+
+ @Override
+ public WorkflowFormTO claimForm(final String taskId) {
+ String authUser = AuthContextUtils.getUsername();
+ Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
+
+ if (!adminUser.equals(authUser)) {
+ List<Task> tasksForUser = engine.getTaskService().createTaskQuery().taskId(taskId).taskCandidateUser(
+ authUser).list();
+ if (tasksForUser.isEmpty()) {
+ throw new WorkflowException(
+ new IllegalArgumentException(authUser + " is not candidate for task " + taskId));
+ }
+ }
+
+ Task task;
+ try {
+ engine.getTaskService().setOwner(taskId, authUser);
+ task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
+ } catch (ActivitiException e) {
+ throw new WorkflowException("While reading task " + taskId, e);
+ }
+
+ return getFormTO(task, checked.getValue());
+ }
+
+ @Override
+ public WorkflowResult<UserPatch> submitForm(final WorkflowFormTO form) {
+ String authUser = AuthContextUtils.getUsername();
+ Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
+
+ if (!checked.getKey().getOwner().equals(authUser)) {
+ throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId() + " assigned to "
+ + checked.getKey().getOwner() + " but submitted by " + authUser));
+ }
+
+ User user = userDAO.findByWorkflowId(checked.getKey().getProcessInstanceId());
+ if (user == null) {
+ throw new NotFoundException("User with workflow id " + checked.getKey().getProcessInstanceId());
+ }
+
+ Set<String> preTasks = getPerformedTasks(user);
+ try {
+ engine.getFormService().submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit());
+ engine.getRuntimeService().setVariable(user.getWorkflowId(), FORM_SUBMITTER, authUser);
+ } catch (ActivitiException e) {
+ throwException(e, "While submitting form for task " + form.getTaskId());
+ }
+
+ Set<String> postTasks = getPerformedTasks(user);
+ postTasks.removeAll(preTasks);
+ postTasks.add(form.getTaskId());
+
+ updateStatus(user);
+ User updated = userDAO.save(user);
+
+ // see if there is any propagation to be done
+ PropagationByResource propByRes = engine.getRuntimeService().getVariable(
+ user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
+
+ // fetch - if available - the encrypted password
+ String clearPassword = null;
+ String encryptedPwd = engine.getRuntimeService().getVariable(user.getWorkflowId(), ENCRYPTED_PWD, String.class);
+ if (StringUtils.isNotBlank(encryptedPwd)) {
+ clearPassword = decrypt(encryptedPwd);
+ }
+
+ // supports approval chains
+ saveForFormSubmit(user, clearPassword, propByRes);
+
+ UserPatch userPatch = engine.getRuntimeService().getVariable(user.getWorkflowId(), USER_PATCH, UserPatch.class);
+ if (userPatch == null) {
+ userPatch = new UserPatch();
+ userPatch.setKey(updated.getKey());
+ userPatch.setPassword(new PasswordPatch.Builder().onSyncope(true).value(clearPassword).build());
+
+ if (propByRes != null) {
+ userPatch.getPassword().getResources().addAll(propByRes.get(ResourceOperation.CREATE));
+ }
+ }
+
++ cleanupHistory(user);
++
+ return new WorkflowResult<>(userPatch, propByRes, postTasks);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/e9ff5c73/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
----------------------------------------------------------------------
diff --cc core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
index 48eeb5c,0000000..f851e08
mode 100644,000000..100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/spring/DomainProcessEngine.java
@@@ -1,108 -1,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.workflow.activiti.spring;
+
+import java.util.Collections;
+import java.util.Map;
++import javax.sql.DataSource;
+import org.activiti.engine.DynamicBpmnService;
+import org.activiti.engine.FormService;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.ManagementService;
+import org.activiti.engine.ProcessEngine;
+import org.activiti.engine.ProcessEngineConfiguration;
+import org.activiti.engine.RepositoryService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.TaskService;
++import org.activiti.engine.impl.ProcessEngineImpl;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+
+/**
+ * {@link ProcessEngine} delegating actual method invocation to the inner map of {@link ProcessEngine} instances,
+ * one for each Syncope domain.
+ */
+public class DomainProcessEngine implements ProcessEngine {
+
+ private final Map<String, ProcessEngine> engines;
+
+ public DomainProcessEngine(final Map<String, ProcessEngine> engines) {
+ this.engines = Collections.synchronizedMap(engines);
+ }
+
+ public Map<String, ProcessEngine> getEngines() {
+ return engines;
+ }
+
+ @Override
+ public String getName() {
+ return engines.get(AuthContextUtils.getDomain()).getName();
+ }
+
+ @Override
+ public void close() {
+ for (ProcessEngine engine : engines.values()) {
+ engine.close();
+ }
+ }
+
+ @Override
+ public RepositoryService getRepositoryService() {
+ return engines.get(AuthContextUtils.getDomain()).getRepositoryService();
+ }
+
+ @Override
+ public RuntimeService getRuntimeService() {
+ return engines.get(AuthContextUtils.getDomain()).getRuntimeService();
+ }
+
+ @Override
+ public FormService getFormService() {
+ return engines.get(AuthContextUtils.getDomain()).getFormService();
+ }
+
+ @Override
+ public TaskService getTaskService() {
+ return engines.get(AuthContextUtils.getDomain()).getTaskService();
+ }
+
+ @Override
+ public HistoryService getHistoryService() {
+ return engines.get(AuthContextUtils.getDomain()).getHistoryService();
+ }
+
+ @Override
+ public IdentityService getIdentityService() {
+ return engines.get(AuthContextUtils.getDomain()).getIdentityService();
+ }
+
+ @Override
+ public ManagementService getManagementService() {
+ return engines.get(AuthContextUtils.getDomain()).getManagementService();
+ }
+
+ @Override
+ public ProcessEngineConfiguration getProcessEngineConfiguration() {
+ return engines.get(AuthContextUtils.getDomain()).getProcessEngineConfiguration();
+ }
+
+ @Override
+ public DynamicBpmnService getDynamicBpmnService() {
+ return engines.get(AuthContextUtils.getDomain()).getDynamicBpmnService();
+ }
+
++ public DataSource getDataSource() {
++ ProcessEngineImpl engine = (ProcessEngineImpl) engines.get(AuthContextUtils.getDomain());
++ return engine.getProcessEngineConfiguration().getDataSource();
++ }
+}
[3/5] syncope git commit: [SYNCOPE-119] Added search options and
checks to match assignable conditions,
for usage with memberships and relationships
Posted by il...@apache.org.
[SYNCOPE-119] Added search options and checks to match assignable conditions, for usage with memberships and relationships
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/bbb051fe
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/bbb051fe
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/bbb051fe
Branch: refs/heads/master
Commit: bbb051feb43291de74d7cec215c63d2d68cbca03
Parents: 7b1cb89
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 25 11:43:25 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 25 12:09:02 2015 +0100
----------------------------------------------------------------------
.../syncope/client/lib/SyncopeClient.java | 5 +-
.../AnyObjectFiqlSearchConditionBuilder.java | 110 ++++++++++++-
.../common/lib/search/AnyObjectProperty.java | 16 ++
.../search/GroupFiqlSearchConditionBuilder.java | 21 ++-
.../common/lib/search/GroupProperty.java | 4 +
.../syncope/common/lib/search/SpecialAttr.java | 31 +++-
.../search/UserFiqlSearchConditionBuilder.java | 80 ++++++++--
.../syncope/common/lib/search/UserProperty.java | 8 +
.../common/lib/types/ClientExceptionType.java | 2 +
.../core/misc/search/SearchCondVisitor.java | 29 +++-
.../misc/search/SearchCondConverterTest.java | 50 +++++-
.../core/persistence/api/dao/AnySearchDAO.java | 8 +
.../core/persistence/api/dao/RealmDAO.java | 3 +
.../api/dao/search/AssignableCond.java | 39 +++++
.../api/dao/search/RelationshipTypeCond.java | 39 +++++
.../persistence/api/dao/search/SearchCond.java | 42 ++++-
.../persistence/jpa/dao/JPAAnySearchDAO.java | 154 +++++++++++++------
.../core/persistence/jpa/dao/JPARealmDAO.java | 11 +-
.../src/main/resources/views.xml | 4 +-
.../persistence/jpa/inner/AnySearchTest.java | 116 +++++++++++++-
.../core/persistence/jpa/inner/GroupTest.java | 2 +-
.../core/persistence/jpa/outer/RealmTest.java | 11 ++
.../test/resources/domains/MasterContent.xml | 9 +-
.../provisioning/api/data/GroupDataBinder.java | 2 +-
.../java/data/AbstractAnyDataBinder.java | 24 +--
.../java/data/AnyObjectDataBinderImpl.java | 116 ++++++++++----
.../java/data/GroupDataBinderImpl.java | 24 ++-
.../java/data/UserDataBinderImpl.java | 116 ++++++++++----
.../rest/cxf/service/AnyObjectServiceImpl.java | 2 +-
.../fit/core/reference/AnyObjectITCase.java | 22 +++
.../fit/core/reference/SearchITCase.java | 135 ++++++++++++++--
.../fit/core/reference/SyncTaskITCase.java | 4 +-
.../syncope/fit/core/reference/UserITCase.java | 2 +-
33 files changed, 1031 insertions(+), 210 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
index 198b585..c2d6250 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClient.java
@@ -93,10 +93,11 @@ public class SyncopeClient {
/**
* Returns a new instance of {@link AnyObjectFiqlSearchConditionBuilder}, for assisted building of FIQL queries.
*
+ * @param type any type
* @return default instance of {@link AnyObjectFiqlSearchConditionBuilder}
*/
- public static AnyObjectFiqlSearchConditionBuilder getAnyObjectSearchConditionBuilder() {
- return new AnyObjectFiqlSearchConditionBuilder();
+ public static AnyObjectFiqlSearchConditionBuilder getAnyObjectSearchConditionBuilder(final String type) {
+ return new AnyObjectFiqlSearchConditionBuilder(type);
}
/**
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
index 67e7e15..0841de3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
@@ -18,8 +18,11 @@
*/
package org.apache.syncope.common.lib.search;
+import java.util.Collections;
import java.util.Map;
import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+import org.apache.cxf.jaxrs.ext.search.client.FiqlSearchConditionBuilder;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
/**
* Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
@@ -27,12 +30,11 @@ import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
*/
public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
- public AnyObjectFiqlSearchConditionBuilder() {
- super();
- }
+ private final String type;
- public AnyObjectFiqlSearchConditionBuilder(final Map<String, String> properties) {
- super(properties);
+ public AnyObjectFiqlSearchConditionBuilder(final String type) {
+ super();
+ this.type = type;
}
@Override
@@ -41,15 +43,59 @@ public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchCondi
}
@Override
+ public String query() {
+ return new FiqlSearchConditionBuilder.Builder(Collections.<String, String>emptyMap()).
+ is(SpecialAttr.TYPE.toString()).equalTo(type).query();
+ }
+
+ @Override
public AnyObjectProperty is(final String property) {
return newBuilderInstance().is(property);
}
- public CompleteCondition type(final String type) {
- return newBuilderInstance().is(SpecialAttr.TYPE.toString()).equalTo(type);
+ public CompleteCondition inGroups(final Long group, final Long... moreGroups) {
+ return newBuilderInstance().
+ is(SpecialAttr.GROUPS.toString()).
+ inGroups(group, moreGroups);
}
- protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
+ public CompleteCondition notInGroups(final Long group, final Long... moreGroups) {
+ return newBuilderInstance().
+ is(SpecialAttr.GROUPS.toString()).
+ notInGroups(group, moreGroups);
+ }
+
+ public CompleteCondition inRelationships(final Long anyType, final Long... moreAnyTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIPS.toString()).
+ inRelationships(anyType, moreAnyTypes);
+ }
+
+ public CompleteCondition notInRelationships(final Long anyType, final Long... moreAnyTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIPS.toString()).
+ notInRelationships(anyType, moreAnyTypes);
+ }
+
+ public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
+ inRelationshipTypes(type, moreTypes);
+ }
+
+ public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
+ notInRelationshipTypes(type, moreTypes);
+ }
+
+ public CompleteCondition isAssignable(final String realm, final String... moreRealms) {
+ return newBuilderInstance().
+ is(SpecialAttr.ASSIGNABLE.toString()).
+ isAssignable(realm, moreRealms);
+ }
+
+ protected class Builder extends AbstractFiqlSearchConditionBuilder.Builder
implements AnyObjectProperty, CompleteCondition {
public Builder(final Map<String, String> properties) {
@@ -61,11 +107,59 @@ public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchCondi
}
@Override
+ public String query() {
+ FiqlSearchConditionBuilder.Builder b = new FiqlSearchConditionBuilder.Builder(this);
+ return b.and(SpecialAttr.TYPE.toString()).equalTo(type).query();
+ }
+
+ @Override
public AnyObjectProperty is(final String property) {
Builder b = new Builder(this);
b.result = property;
return b;
}
+ @Override
+ public CompleteCondition inGroups(final Long group, final Long... moreGroups) {
+ this.result = SpecialAttr.GROUPS.toString();
+ return condition(FiqlParser.EQ, group, (Object[]) moreGroups);
+ }
+
+ @Override
+ public CompleteCondition notInGroups(final Long group, final Long... moreGroups) {
+ this.result = SpecialAttr.GROUPS.toString();
+ return condition(FiqlParser.NEQ, group, (Object[]) moreGroups);
+ }
+
+ @Override
+ public CompleteCondition inRelationships(final Long anyObject, final Long... moreAnyObjects) {
+ this.result = SpecialAttr.RELATIONSHIPS.toString();
+ return condition(FiqlParser.EQ, anyObject, (Object[]) moreAnyObjects);
+ }
+
+ @Override
+ public CompleteCondition notInRelationships(final Long group, final Long... moreRelationships) {
+ this.result = SpecialAttr.RELATIONSHIPS.toString();
+ return condition(FiqlParser.NEQ, group, (Object[]) moreRelationships);
+ }
+
+ @Override
+ public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+ this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
+ return condition(FiqlParser.EQ, type, (Object[]) moreTypes);
+ }
+
+ @Override
+ public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+ this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
+ return condition(FiqlParser.NEQ, type, (Object[]) moreTypes);
+ }
+
+ @Override
+ public CompleteCondition isAssignable(final String realm, final String... moreRealms) {
+ this.result = SpecialAttr.ASSIGNABLE.toString();
+ return condition(FiqlParser.EQ, realm, (Object[]) moreRealms);
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
index c675712..47de383 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
@@ -18,6 +18,22 @@
*/
package org.apache.syncope.common.lib.search;
+import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+
public interface AnyObjectProperty extends SyncopeProperty {
+ CompleteCondition inGroups(Long group, Long... moreGroups);
+
+ CompleteCondition notInGroups(Long group, Long... moreGroups);
+
+ CompleteCondition inRelationships(Long anyObject, Long... moreAnyObjects);
+
+ CompleteCondition notInRelationships(Long anyObject, Long... moreAnyObjects);
+
+ CompleteCondition inRelationshipTypes(String type, String... moreTypes);
+
+ CompleteCondition notInRelationshipTypes(String type, String... moreTypes);
+
+ CompleteCondition isAssignable(String realm, String... moreRealms);
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
index aaa56d7..9a2bc3f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.search;
import java.util.Map;
import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
/**
* Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
@@ -27,14 +28,6 @@ import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
*/
public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
- public GroupFiqlSearchConditionBuilder() {
- super();
- }
-
- public GroupFiqlSearchConditionBuilder(final Map<String, String> properties) {
- super(properties);
- }
-
@Override
protected Builder newBuilderInstance() {
return new Builder(properties);
@@ -45,6 +38,12 @@ public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchCondition
return newBuilderInstance().is(property);
}
+ public CompleteCondition isAssignable(final String realm, final String... moreRealms) {
+ return newBuilderInstance().
+ is(SpecialAttr.ASSIGNABLE.toString()).
+ isAssignable(realm, moreRealms);
+ }
+
protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
implements GroupProperty, CompleteCondition {
@@ -63,5 +62,11 @@ public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchCondition
return b;
}
+ @Override
+ public CompleteCondition isAssignable(final String realm, final String... moreRealms) {
+ this.result = SpecialAttr.ASSIGNABLE.toString();
+ return condition(FiqlParser.EQ, realm, (Object[]) moreRealms);
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
index 0eb7480..8dc375e 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
@@ -18,6 +18,10 @@
*/
package org.apache.syncope.common.lib.search;
+import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+
public interface GroupProperty extends SyncopeProperty {
+ CompleteCondition isAssignable(String realm, String... moreRealms);
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
index 551a0ad..1b1f484 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
@@ -24,11 +24,40 @@ import org.apache.commons.collections4.Predicate;
public enum SpecialAttr {
+ /**
+ * Applies to users, groups and any objects.
+ *//**
+ * Applies to users, groups and any objects.
+ */
NULL("$null"),
+ /**
+ * Applies to any objects.
+ */
TYPE("$type"),
+ /**
+ * Applies to users, groups and any objects.
+ */
RESOURCES("$resources"),
+ /**
+ * Applies to users and any objects.
+ */
GROUPS("$groups"),
- ROLES("$roles");
+ /**
+ * Applies to users and any objects.
+ */
+ RELATIONSHIPS("$relationships"),
+ /**
+ * Applies to users and any objects.
+ */
+ RELATIONSHIP_TYPES("$relationshipTypes"),
+ /**
+ * Applies to users.
+ */
+ ROLES("$roles"),
+ /**
+ * Applies to groups and any objects.
+ */
+ ASSIGNABLE("$assignable");
private final String literal;
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
index 323e38b..30e89dd 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
@@ -28,14 +28,6 @@ import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
*/
public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
- public UserFiqlSearchConditionBuilder() {
- super();
- }
-
- public UserFiqlSearchConditionBuilder(final Map<String, String> properties) {
- super(properties);
- }
-
@Override
protected Builder newBuilderInstance() {
return new Builder(properties);
@@ -47,20 +39,58 @@ public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionB
}
public CompleteCondition inGroups(final Long group, final Long... moreGroups) {
- return newBuilderInstance().is(SpecialAttr.GROUPS.toString()).inGroups(group, moreGroups);
+ return newBuilderInstance().
+ is(SpecialAttr.GROUPS.toString()).
+ inGroups(group, moreGroups);
+ }
+
+ public CompleteCondition notInGroups(final Long group, final Long... moreGroups) {
+ return newBuilderInstance().
+ is(SpecialAttr.GROUPS.toString()).
+ notInGroups(group, moreGroups);
+ }
+
+ public CompleteCondition inRelationships(final Long anyType, final Long... moreAnyTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIPS.toString()).
+ inRelationships(anyType, moreAnyTypes);
+ }
+
+ public CompleteCondition notInRelationships(final Long anyType, final Long... moreAnyTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIPS.toString()).
+ notInRelationships(anyType, moreAnyTypes);
+ }
+
+ public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
+ inRelationshipTypes(type, moreTypes);
+ }
+
+ public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+ return newBuilderInstance().
+ is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
+ notInRelationshipTypes(type, moreTypes);
}
public CompleteCondition inRoles(final String role, final String... moreRoles) {
- return newBuilderInstance().is(SpecialAttr.ROLES.toString()).inRoles(role, moreRoles);
+ return newBuilderInstance().
+ is(SpecialAttr.ROLES.toString()).
+ inRoles(role, moreRoles);
}
- public CompleteCondition notInGroups(final Long group, final Long... moreGroups) {
- return newBuilderInstance().is(SpecialAttr.GROUPS.toString()).notInGroups(group, moreGroups);
+ public CompleteCondition notInRoles(final String role, final String... moreRoles) {
+ return newBuilderInstance().
+ is(SpecialAttr.ROLES.toString()).
+ notInRoles(role, moreRoles);
}
@Override
public CompleteCondition hasResources(final String resource, final String... moreResources) {
- return newBuilderInstance().is(SpecialAttr.RESOURCES.toString()).hasResources(resource, moreResources);
+ return newBuilderInstance().
+ is(SpecialAttr.RESOURCES.toString()).
+ hasResources(resource, moreResources);
}
@Override
@@ -99,6 +129,30 @@ public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionB
}
@Override
+ public CompleteCondition inRelationships(final Long anyObject, final Long... moreAnyObjects) {
+ this.result = SpecialAttr.RELATIONSHIPS.toString();
+ return condition(FiqlParser.EQ, anyObject, (Object[]) moreAnyObjects);
+ }
+
+ @Override
+ public CompleteCondition notInRelationships(final Long anyObject, final Long... moreAnyObjects) {
+ this.result = SpecialAttr.RELATIONSHIPS.toString();
+ return condition(FiqlParser.NEQ, anyObject, (Object[]) moreAnyObjects);
+ }
+
+ @Override
+ public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+ this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
+ return condition(FiqlParser.EQ, type, (Object[]) moreTypes);
+ }
+
+ @Override
+ public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+ this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
+ return condition(FiqlParser.NEQ, type, (Object[]) moreTypes);
+ }
+
+ @Override
public CompleteCondition inRoles(final String role, final String... moreRoles) {
this.result = SpecialAttr.ROLES.toString();
return condition(FiqlParser.EQ, role, (Object[]) moreRoles);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
index 210274c..9294ab0 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
@@ -26,6 +26,14 @@ public interface UserProperty extends SyncopeProperty {
CompleteCondition notInGroups(Long group, Long... moreGroups);
+ CompleteCondition inRelationships(Long anyObject, Long... moreAnyObjects);
+
+ CompleteCondition notInRelationships(Long anyObject, Long... moreAnyObjects);
+
+ CompleteCondition inRelationshipTypes(String type, String... moreTypes);
+
+ CompleteCondition notInRelationshipTypes(String type, String... moreTypes);
+
CompleteCondition inRoles(String role, String... moreRoles);
CompleteCondition notInRoles(String role, String... moreRoles);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 68ad199..dfc5fe2 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -40,6 +40,7 @@ public enum ClientExceptionType {
InvalidProvision(Response.Status.BAD_REQUEST),
InvalidReport(Response.Status.BAD_REQUEST),
InvalidReportExec(Response.Status.BAD_REQUEST),
+ InvalidRelationship(Response.Status.BAD_REQUEST),
InvalidRelationshipType(Response.Status.BAD_REQUEST),
InvalidAnyType(Response.Status.BAD_REQUEST),
InvalidAnyObject(Response.Status.BAD_REQUEST),
@@ -52,6 +53,7 @@ public enum ClientExceptionType {
InvalidDerSchema(Response.Status.BAD_REQUEST),
InvalidVirSchema(Response.Status.BAD_REQUEST),
InvalidMapping(Response.Status.BAD_REQUEST),
+ InvalidMembership(Response.Status.BAD_REQUEST),
InvalidRealm(Response.Status.BAD_REQUEST),
InvalidRole(Response.Status.BAD_REQUEST),
InvalidUser(Response.Status.BAD_REQUEST),
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
index 6b067ca..1fe03d2 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/search/SearchCondVisitor.java
@@ -38,6 +38,9 @@ import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
/**
* Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
@@ -105,22 +108,40 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
leaf = SearchCond.getLeafCond(typeCond);
break;
+ case RESOURCES:
+ ResourceCond resourceCond = new ResourceCond();
+ resourceCond.setResourceName(value);
+ leaf = SearchCond.getLeafCond(resourceCond);
+ break;
+
case GROUPS:
MembershipCond groupCond = new MembershipCond();
groupCond.setGroupKey(Long.valueOf(value));
leaf = SearchCond.getLeafCond(groupCond);
break;
+ case RELATIONSHIPS:
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(Long.valueOf(value));
+ leaf = SearchCond.getLeafCond(relationshipCond);
+ break;
+
+ case RELATIONSHIP_TYPES:
+ RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+ relationshipTypeCond.setRelationshipTypeKey(value);
+ leaf = SearchCond.getLeafCond(relationshipTypeCond);
+ break;
+
case ROLES:
RoleCond roleCond = new RoleCond();
roleCond.setRoleKey(value);
leaf = SearchCond.getLeafCond(roleCond);
break;
- case RESOURCES:
- ResourceCond resourceCond = new ResourceCond();
- resourceCond.setResourceName(value);
- leaf = SearchCond.getLeafCond(resourceCond);
+ case ASSIGNABLE:
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath(value);
+ leaf = SearchCond.getLeafCond(assignableCond);
break;
default:
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
----------------------------------------------------------------------
diff --git a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
index 29f3c64..e081ffa 100644
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.misc.search;
import static org.junit.Assert.assertEquals;
import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
+import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
import org.apache.syncope.common.lib.search.SpecialAttr;
import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -30,6 +31,9 @@ import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
import org.junit.Test;
public class SearchCondConverterTest {
@@ -85,6 +89,35 @@ public class SearchCondConverterTest {
}
@Test
+ public void relationships() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationships(1L).query();
+ assertEquals(SpecialAttr.RELATIONSHIPS + "==1", fiqlExpression);
+
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(1L);
+ SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
+ public void relationshipTypes() {
+ String fiqlExpression = new UserFiqlSearchConditionBuilder().inRelationshipTypes("type1").query();
+ assertEquals(SpecialAttr.RELATIONSHIP_TYPES + "==type1", fiqlExpression);
+
+ RelationshipTypeCond relationshipCond = new RelationshipTypeCond();
+ relationshipCond.setRelationshipTypeKey("type1");
+ SearchCond simpleCond = SearchCond.getLeafCond(relationshipCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+
+ fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").inRelationshipTypes("neighborhood").query();
+ assertEquals(
+ SpecialAttr.RELATIONSHIP_TYPES + "==neighborhood;" + SpecialAttr.TYPE + "==PRINTER",
+ fiqlExpression);
+ }
+
+ @Test
public void groups() {
String fiqlExpression = new UserFiqlSearchConditionBuilder().inGroups(1L).query();
assertEquals(SpecialAttr.GROUPS + "==1", fiqlExpression);
@@ -121,8 +154,20 @@ public class SearchCondConverterTest {
}
@Test
+ public void assignable() {
+ String fiqlExpression = new GroupFiqlSearchConditionBuilder().isAssignable("/even/two").query();
+ assertEquals(SpecialAttr.ASSIGNABLE + "==/even/two", fiqlExpression);
+
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath("/even/two");
+ SearchCond simpleCond = SearchCond.getLeafCond(assignableCond);
+
+ assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+ }
+
+ @Test
public void type() {
- String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder().type("PRINTER").query();
+ String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder("PRINTER").query();
assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
AnyTypeCond acond = new AnyTypeCond();
@@ -156,6 +201,9 @@ public class SearchCondConverterTest {
String fiqlExpression = new UserFiqlSearchConditionBuilder().
is("fullname").equalTo("*o*", "*i*", "*ini").query();
assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
+ fiqlExpression = new UserFiqlSearchConditionBuilder().
+ is("fullname").equalTo("*o*").or("fullname").equalTo("*i*").or("fullname").equalTo("*ini").query();
+ assertEquals("fullname==*o*,fullname==*i*,fullname==*ini", fiqlExpression);
AttributeCond fullnameLeafCond1 = new AttributeCond(AttributeCond.Type.LIKE);
fullnameLeafCond1.setSchema("fullname");
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
index 401d957..67e85f2 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnySearchDAO.java
@@ -36,6 +36,14 @@ public interface AnySearchDAO extends DAO<Any<?>, Long> {
int count(Set<String> adminRealms, SearchCond searchCondition, AnyTypeKind kind);
/**
+ * @param realmFullPath for use with {@link org.apache.syncope.core.persistence.api.dao.search.AssignableCond}
+ * @param kind any object
+ * @param <T> any
+ * @return the list of any objects matching the given search condition
+ */
+ <T extends Any<?>> List<T> searchAssignable(String realmFullPath, AnyTypeKind kind);
+
+ /**
* @param searchCondition the search condition
* @param kind any object
* @param <T> any
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
index 515779e..f8c94b6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
@@ -19,11 +19,14 @@
package org.apache.syncope.core.persistence.api.dao;
import java.util.List;
+import java.util.regex.Pattern;
import org.apache.syncope.core.persistence.api.entity.Policy;
import org.apache.syncope.core.persistence.api.entity.Realm;
public interface RealmDAO extends DAO<Realm, Long> {
+ Pattern PATH_PATTERN = Pattern.compile("^(/[A-Za-z0-9]+)+");
+
Realm getRoot();
Realm find(Long key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
new file mode 100644
index 0000000..0ece01b
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
@@ -0,0 +1,39 @@
+/*
+ * 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.persistence.api.dao.search;
+
+public class AssignableCond extends AbstractSearchCond {
+
+ private static final long serialVersionUID = 1237627275756159522L;
+
+ private String realmFullPath;
+
+ public String getRealmFullPath() {
+ return realmFullPath;
+ }
+
+ public void setRealmFullPath(final String realmFullPath) {
+ this.realmFullPath = realmFullPath;
+ }
+
+ @Override
+ public final boolean isValid() {
+ return realmFullPath != null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
new file mode 100644
index 0000000..d120e62
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
@@ -0,0 +1,39 @@
+/*
+ * 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.persistence.api.dao.search;
+
+public class RelationshipTypeCond extends AbstractSearchCond {
+
+ private static final long serialVersionUID = 906241367466433419L;
+
+ private String relationshipTypeKey;
+
+ public String getRelationshipTypeKey() {
+ return relationshipTypeKey;
+ }
+
+ public void setRelationshipTypeKey(final String relationshipTypeKey) {
+ this.relationshipTypeKey = relationshipTypeKey;
+ }
+
+ @Override
+ public final boolean isValid() {
+ return relationshipTypeKey != null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
index 14641c1..a33ccf3 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
@@ -43,12 +43,16 @@ public class SearchCond extends AbstractSearchCond {
private RelationshipCond relationshipCond;
+ private RelationshipTypeCond relationshipTypeCond;
+
private MembershipCond membershipCond;
private RoleCond roleCond;
private ResourceCond resourceCond;
+ private AssignableCond assignableCond;
+
private SearchCond leftNodeCond;
private SearchCond rightNodeCond;
@@ -84,6 +88,15 @@ public class SearchCond extends AbstractSearchCond {
return nodeCond;
}
+ public static SearchCond getLeafCond(final RelationshipTypeCond relationshipTypeCond) {
+ SearchCond nodeCond = new SearchCond();
+
+ nodeCond.type = Type.LEAF;
+ nodeCond.relationshipTypeCond = relationshipTypeCond;
+
+ return nodeCond;
+ }
+
public static SearchCond getLeafCond(final MembershipCond membershipCond) {
SearchCond nodeCond = new SearchCond();
@@ -111,6 +124,15 @@ public class SearchCond extends AbstractSearchCond {
return nodeCond;
}
+ public static SearchCond getLeafCond(final AssignableCond assignableCond) {
+ SearchCond nodeCond = new SearchCond();
+
+ nodeCond.type = Type.LEAF;
+ nodeCond.assignableCond = assignableCond;
+
+ return nodeCond;
+ }
+
public static SearchCond getNotLeafCond(final AttributeCond attributeCond) {
SearchCond nodeCond = getLeafCond(attributeCond);
nodeCond.type = Type.NOT_LEAF;
@@ -216,6 +238,14 @@ public class SearchCond extends AbstractSearchCond {
this.relationshipCond = relationshipCond;
}
+ public RelationshipTypeCond getRelationshipTypeCond() {
+ return relationshipTypeCond;
+ }
+
+ public void setRelationshipTypeCond(final RelationshipTypeCond relationshipTypeCond) {
+ this.relationshipTypeCond = relationshipTypeCond;
+ }
+
public MembershipCond getMembershipCond() {
return membershipCond;
}
@@ -240,6 +270,14 @@ public class SearchCond extends AbstractSearchCond {
this.resourceCond = resourceCond;
}
+ public AssignableCond getAssignableCond() {
+ return assignableCond;
+ }
+
+ public void setAssignableCond(final AssignableCond assignableCond) {
+ this.assignableCond = assignableCond;
+ }
+
public SearchCond getLeftNodeCond() {
return leftNodeCond;
}
@@ -307,8 +345,8 @@ public class SearchCond extends AbstractSearchCond {
case LEAF:
case NOT_LEAF:
isValid = (anyTypeCond != null || anyCond != null || attributeCond != null
- || relationshipCond != null || membershipCond != null
- || roleCond != null || resourceCond != null)
+ || relationshipCond != null || relationshipTypeCond != null || membershipCond != null
+ || roleCond != null || resourceCond != null || assignableCond != null)
&& (anyTypeCond == null || anyTypeCond.isValid())
&& (anyCond == null || anyCond.isValid())
&& (attributeCond == null || attributeCond.isValid())
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index 64c850b..c1f6fe2 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -55,7 +55,9 @@ import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
@@ -65,12 +67,14 @@ import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ReflectionUtils;
@Repository
public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySearchDAO {
- private static final String EMPTY_ATTR_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
+ private static final String EMPTY_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
@Autowired
private RealmDAO realmDAO;
@@ -150,6 +154,14 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
return ((Number) countQuery.getSingleResult()).intValue();
}
+ @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
+ @Override
+ public <T extends Any<?>> List<T> searchAssignable(final String realmFullPath, final AnyTypeKind kind) {
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath(realmFullPath);
+ return search(SearchCond.getLeafCond(assignableCond), kind);
+ }
+
@Override
public <T extends Any<?>> List<T> search(final SearchCond searchCondition, final AnyTypeKind typeKind) {
return search(searchCondition, Collections.<OrderByClause>emptyList(), typeKind);
@@ -406,7 +418,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
}
private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters,
- final AnyTypeKind type, final SearchSupport svs) {
+ final AnyTypeKind anyTypeKind, final SearchSupport svs) {
StringBuilder query = new StringBuilder();
@@ -414,51 +426,55 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
case LEAF:
case NOT_LEAF:
- if (nodeCond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == type) {
+ if (nodeCond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == anyTypeKind) {
query.append(getQuery(nodeCond.getAnyTypeCond(),
nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
- }
- if (nodeCond.getRelationshipCond() != null
- && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+ } else if (nodeCond.getRelationshipTypeCond() != null
+ && (AnyTypeKind.USER == anyTypeKind || AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
+
+ query.append(getQuery(nodeCond.getRelationshipTypeCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+ } else if (nodeCond.getRelationshipCond() != null
+ && (AnyTypeKind.USER == anyTypeKind || AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
query.append(getQuery(nodeCond.getRelationshipCond(),
nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
- }
- if (nodeCond.getMembershipCond() != null
- && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+ } else if (nodeCond.getMembershipCond() != null
+ && (AnyTypeKind.USER == anyTypeKind || AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
query.append(getQuery(nodeCond.getMembershipCond(),
nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
- }
- if (nodeCond.getRoleCond() != null && AnyTypeKind.USER == type) {
+ } else if (nodeCond.getAssignableCond() != null
+ && (AnyTypeKind.GROUP == anyTypeKind || AnyTypeKind.ANY_OBJECT == anyTypeKind)) {
+
+ query.append(getQuery(nodeCond.getAssignableCond(), parameters, anyTypeKind, svs));
+ } else if (nodeCond.getRoleCond() != null && AnyTypeKind.USER == anyTypeKind) {
query.append(getQuery(nodeCond.getRoleCond(),
nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
- }
- if (nodeCond.getResourceCond() != null) {
+ } else if (nodeCond.getResourceCond() != null) {
query.append(getQuery(nodeCond.getResourceCond(),
- nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
- }
- if (nodeCond.getAttributeCond() != null) {
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, anyTypeKind, svs));
+ } else if (nodeCond.getAttributeCond() != null) {
query.append(getQuery(nodeCond.getAttributeCond(),
- nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
- }
- if (nodeCond.getAnyCond() != null) {
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, anyTypeKind, svs));
+ } else if (nodeCond.getAnyCond() != null) {
query.append(getQuery(nodeCond.getAnyCond(),
- nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, anyTypeKind,
+ svs));
}
break;
case AND:
- query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+ query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, anyTypeKind, svs)).
append(" AND any_id IN ( ").
- append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+ append(getQuery(nodeCond.getRightNodeCond(), parameters, anyTypeKind, svs)).
append(")");
break;
case OR:
- query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+ query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, anyTypeKind, svs)).
append(" OR any_id IN ( ").
- append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+ append(getQuery(nodeCond.getRightNodeCond(), parameters, anyTypeKind, svs)).
append(")");
break;
@@ -485,6 +501,29 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
return query.toString();
}
+ private String getQuery(final RelationshipTypeCond cond, final boolean not, final List<Object> parameters,
+ final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT any_id ").append("FROM ").
+ append(svs.relationship().name).
+ append(" WHERE type=?").append(setParameter(parameters, cond.getRelationshipTypeKey())).
+ append(" UNION SELECT right_any_id AS any_id FROM ").
+ append(svs.relationship().name).
+ append(" WHERE type=?").append(setParameter(parameters, cond.getRelationshipTypeKey())).
+ append(')');
+
+ return query.toString();
+ }
+
private String getQuery(final RelationshipCond cond, final boolean not, final List<Object> parameters,
final SearchSupport svs) {
@@ -499,7 +538,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
query.append("SELECT DISTINCT any_id ").append("FROM ").
append(svs.relationship().name).append(" WHERE ").
- append("right_anyObject_id=?").append(setParameter(parameters, cond.getAnyObjectKey())).
+ append("right_any_id=?").append(setParameter(parameters, cond.getAnyObjectKey())).
append(')');
return query.toString();
@@ -570,7 +609,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
private String getQuery(final ResourceCond cond, final boolean not, final List<Object> parameters,
final AnyTypeKind typeKind, final SearchSupport svs) {
- final StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
append(svs.field().name).append(" WHERE ");
if (not) {
@@ -596,6 +635,24 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
return query.toString();
}
+ private String getQuery(final AssignableCond cond, final List<Object> parameters, final AnyTypeKind typeKind,
+ final SearchSupport svs) {
+
+ Realm realm = realmDAO.find(cond.getRealmFullPath());
+ if (realm == null) {
+ return EMPTY_QUERY;
+ }
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+ for (Realm current = realm; current.getParent() != null; current = current.getParent()) {
+ query.append("realm_id=?").append(setParameter(parameters, current.getKey())).append(" OR ");
+ }
+ query.setLength(query.length() - 4);
+
+ return query.toString();
+ }
+
private void fillAttributeQuery(final StringBuilder query, final PlainAttrValue attrValue,
final PlainSchema schema, final AttributeCond cond, final boolean not,
final List<Object> parameters, final SearchSupport svs) {
@@ -696,7 +753,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
PlainSchema schema = schemaDAO.find(cond.getSchema());
if (schema == null) {
LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
- return EMPTY_ATTR_QUERY;
+ return EMPTY_QUERY;
}
PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
@@ -708,27 +765,31 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
}
} catch (ValidationException e) {
LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
- return EMPTY_ATTR_QUERY;
+ return EMPTY_QUERY;
}
StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ");
- if (cond.getType() == AttributeCond.Type.ISNOTNULL) {
- query.append(svs.field().name).
- append(" WHERE any_id NOT IN (SELECT any_id FROM ").
- append(svs.nullAttr().name).
- append(" WHERE schema_name='").append(schema.getKey()).append("')");
- } else if (cond.getType() == AttributeCond.Type.ISNULL) {
- query.append(svs.nullAttr().name).
- append(" WHERE schema_name='").append(schema.getKey()).append("'");
- } else {
- if (schema.isUniqueConstraint()) {
- query.append(svs.uniqueAttr().name);
- } else {
- query.append(svs.attr().name);
- }
- query.append(" WHERE schema_name='").append(schema.getKey());
+ switch (cond.getType()) {
+ case ISNOTNULL:
+ query.append(svs.field().name).
+ append(" WHERE any_id NOT IN (SELECT any_id FROM ").
+ append(svs.nullAttr().name).
+ append(" WHERE schema_name='").append(schema.getKey()).append("')");
+ break;
- fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+ case ISNULL:
+ query.append(svs.nullAttr().name).
+ append(" WHERE schema_name='").append(schema.getKey()).append("'");
+ break;
+
+ default:
+ if (schema.isUniqueConstraint()) {
+ query.append(svs.uniqueAttr().name);
+ } else {
+ query.append(svs.attr().name);
+ }
+ query.append(" WHERE schema_name='").append(schema.getKey());
+ fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
}
return query.toString();
@@ -748,7 +809,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), cond.getSchema());
if (anyField == null) {
LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
- return EMPTY_ATTR_QUERY;
+ return EMPTY_QUERY;
}
PlainSchema schema = new JPAPlainSchema();
@@ -760,7 +821,6 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
}
// Deal with any Integer fields logically mapping to boolean values
- // (JPAGroup.inheritPlainAttrs, for example)
boolean foundBooleanMin = false;
boolean foundBooleanMax = false;
if (Integer.class.equals(anyField.getType())) {
@@ -806,7 +866,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>, Long> implements AnySea
schema.getValidator().validate(cond.getExpression(), attrValue);
} catch (ValidationException e) {
LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
- return EMPTY_ATTR_QUERY;
+ return EMPTY_QUERY;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
index 2733388..1261a5f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARealmDAO.java
@@ -21,7 +21,6 @@ package org.apache.syncope.core.persistence.jpa.dao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.regex.Pattern;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import org.apache.commons.collections4.CollectionUtils;
@@ -44,8 +43,6 @@ import org.springframework.transaction.annotation.Transactional;
@Repository
public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
- private static final Pattern PATH_PATTERN = Pattern.compile("^(/[A-Za-z0-9]+)+");
-
@Autowired
private RoleDAO roleDAO;
@@ -124,11 +121,9 @@ public class JPARealmDAO extends AbstractDAO<Realm, Long> implements RealmDAO {
return Collections.<Realm>emptyList();
}
- StringBuilder queryString = new StringBuilder("SELECT e FROM ").
- append(JPARealm.class.getSimpleName()).append(" e WHERE e.").
- append(policy instanceof AccountPolicy ? "accountPolicy" : "passwordPolicy").append("=:policy");
-
- TypedQuery<Realm> query = entityManager().createQuery(queryString.toString(), Realm.class);
+ TypedQuery<Realm> query = entityManager().createQuery(
+ "SELECT e FROM " + JPARealm.class.getSimpleName() + " e WHERE e."
+ + (policy instanceof AccountPolicy ? "accountPolicy" : "passwordPolicy") + "=:policy", Realm.class);
query.setParameter("policy", policy);
List<Realm> result = new ArrayList<>();
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/main/resources/views.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/views.xml b/core/persistence-jpa/src/main/resources/views.xml
index fd0bf9c..48c801e 100644
--- a/core/persistence-jpa/src/main/resources/views.xml
+++ b/core/persistence-jpa/src/main/resources/views.xml
@@ -70,7 +70,7 @@ under the License.
<entry key="user_search_urelationship">
CREATE VIEW user_search_urelationship AS
- SELECT m.user_id AS any_id, m.anyObject_id AS anyObject_id
+ SELECT m.user_id AS any_id, m.anyObject_id AS right_any_id, m.type_name AS type
FROM URelationship m
</entry>
<entry key="user_search_umembership">
@@ -163,7 +163,7 @@ under the License.
<entry key="anyObject_search_arelationship">
CREATE VIEW anyObject_search_arelationship AS
- SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_anyObject_id
+ SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_any_id, m.type_name AS type
FROM ARelationship m
</entry>
<entry key="anyObject_search_amembership">
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index 48c09d6..4045a76 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -44,7 +44,10 @@ import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
+import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -73,9 +76,13 @@ public class AnySearchTest extends AbstractTest {
AnyObject anyObject = anyObjectDAO.find(1L);
assertNotNull(anyObject);
- RelationshipCond cond = new RelationshipCond();
- cond.setAnyObjectKey(2L);
- assertTrue(searchDAO.matches(anyObject, SearchCond.getLeafCond(cond), AnyTypeKind.ANY_OBJECT));
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(2L);
+ assertTrue(searchDAO.matches(anyObject, SearchCond.getLeafCond(relationshipCond), AnyTypeKind.ANY_OBJECT));
+
+ RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+ relationshipTypeCond.setRelationshipTypeKey("neighborhood");
+ assertTrue(searchDAO.matches(anyObject, SearchCond.getLeafCond(relationshipTypeCond), AnyTypeKind.ANY_OBJECT));
}
@Test
@@ -93,6 +100,17 @@ public class AnySearchTest extends AbstractTest {
RoleCond roleCond = new RoleCond();
roleCond.setRoleKey("Other");
assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(roleCond), AnyTypeKind.USER));
+
+ user = userDAO.find(4L);
+ assertNotNull(user);
+
+ RelationshipCond relationshipCond = new RelationshipCond();
+ relationshipCond.setAnyObjectKey(1L);
+ assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(relationshipCond), AnyTypeKind.USER));
+
+ RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+ relationshipTypeCond.setRelationshipTypeKey("neighborhood");
+ assertTrue(searchDAO.matches(user, SearchCond.getLeafCond(relationshipTypeCond), AnyTypeKind.USER));
}
@Test
@@ -384,7 +402,7 @@ public class AnySearchTest extends AbstractTest {
List<AnyObject> printers = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT);
assertNotNull(printers);
- assertEquals(2, printers.size());
+ assertEquals(3, printers.size());
tcond.setAnyTypeName("UNEXISTING");
printers = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT);
@@ -393,6 +411,51 @@ public class AnySearchTest extends AbstractTest {
}
@Test
+ public void searchByRelationshipType() {
+ // 1. first search for printers involved in "neighborhood" relationship
+ RelationshipTypeCond relationshipTypeCond = new RelationshipTypeCond();
+ relationshipTypeCond.setRelationshipTypeKey("neighborhood");
+
+ AnyTypeCond tcond = new AnyTypeCond();
+ tcond.setAnyTypeName("PRINTER");
+
+ SearchCond searchCondition = SearchCond.getAndCond(
+ SearchCond.getLeafCond(relationshipTypeCond), SearchCond.getLeafCond(tcond));
+ assertTrue(searchCondition.isValid());
+
+ List<Any<?>> matching = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT);
+ assertNotNull(matching);
+ assertEquals(2, matching.size());
+ assertTrue(CollectionUtils.exists(matching, new Predicate<Any<?>>() {
+
+ @Override
+ public boolean evaluate(final Any<?> any) {
+ return any.getKey() == 1L;
+ }
+ }));
+ assertTrue(CollectionUtils.exists(matching, new Predicate<Any<?>>() {
+
+ @Override
+ public boolean evaluate(final Any<?> any) {
+ return any.getKey() == 2L;
+ }
+ }));
+
+ // 2. search for users involved in "neighborhood" relationship
+ searchCondition = SearchCond.getLeafCond(relationshipTypeCond);
+ matching = searchDAO.search(searchCondition, AnyTypeKind.USER);
+ assertNotNull(matching);
+ assertEquals(2, matching.size());
+ assertTrue(CollectionUtils.exists(matching, new Predicate<Any<?>>() {
+
+ @Override
+ public boolean evaluate(final Any<?> any) {
+ return any.getKey() == 4L;
+ }
+ }));
+ }
+
+ @Test
public void userOrderBy() {
AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.EQ);
usernameLeafCond.setSchema("username");
@@ -414,7 +477,8 @@ public class AnySearchTest extends AbstractTest {
orderByClauses.add(orderByClause);
List<User> users = searchDAO.search(searchCondition, orderByClauses, AnyTypeKind.USER);
- assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER),
+ assertEquals(
+ searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.USER),
users.size());
}
@@ -431,12 +495,50 @@ public class AnySearchTest extends AbstractTest {
List<Group> groups = searchDAO.search(
searchCondition, Collections.singletonList(orderByClause), AnyTypeKind.GROUP);
- assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
- searchCondition, AnyTypeKind.GROUP),
+ assertEquals(
+ searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.GROUP),
groups.size());
}
@Test
+ public void assignable() {
+ AssignableCond assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath("/even/two");
+ SearchCond searchCondition = SearchCond.getLeafCond(assignableCond);
+ assertTrue(searchCondition.isValid());
+
+ List<Group> groups = searchDAO.search(searchCondition, AnyTypeKind.GROUP);
+ assertTrue(CollectionUtils.exists(groups, new Predicate<Group>() {
+
+ @Override
+ public boolean evaluate(final Group group) {
+ return group.getKey().equals(15L);
+ }
+ }));
+ assertFalse(CollectionUtils.exists(groups, new Predicate<Group>() {
+
+ @Override
+ public boolean evaluate(final Group group) {
+ return group.getKey().equals(16L);
+ }
+ }));
+
+ assignableCond = new AssignableCond();
+ assignableCond.setRealmFullPath("/odd");
+ searchCondition = SearchCond.getLeafCond(assignableCond);
+ assertTrue(searchCondition.isValid());
+
+ List<AnyObject> anyObjects = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT);
+ assertFalse(CollectionUtils.exists(anyObjects, new Predicate<AnyObject>() {
+
+ @Override
+ public boolean evaluate(final AnyObject anyObject) {
+ return anyObject.getKey().equals(3L);
+ }
+ }));
+ }
+
+ @Test
public void issue202() {
ResourceCond ws2 = new ResourceCond();
ws2.setResourceName("ws-target-resource-2");
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
index 9d449be..c4dba81 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
@@ -48,7 +48,7 @@ public class GroupTest extends AbstractTest {
@Test
public void findAll() {
List<Group> list = groupDAO.findAll();
- assertEquals("did not get expected number of groups ", 15, list.size());
+ assertEquals("did not get expected number of groups ", 16, list.size());
}
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
index 2b67e6a..d1bb773 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
@@ -22,10 +22,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.RoleDAO;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.jpa.AbstractTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -40,11 +42,20 @@ public class RealmTest extends AbstractTest {
@Autowired
private RoleDAO roleDAO;
+ @Autowired
+ private GroupDAO groupDAO;
+
@Test
public void test() {
Realm realm = realmDAO.find("/odd");
assertNotNull(realm);
+ // need to remove this group in order to remove the realm, which is otherwise empty
+ Group group = groupDAO.find(16L);
+ assertNotNull(group);
+ assertEquals(realm, group.getRealm());
+ groupDAO.delete(group);
+
Role role = roleDAO.find("User reviewer");
assertTrue(role.getRealms().contains(realm));
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index b4c5a97..44335eb 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -167,6 +167,9 @@ under the License.
<AnyObject id="2" realm_id="1" type_name="PRINTER"
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+ <AnyObject id="3" realm_id="4" type_name="PRINTER"
+ creator="admin" lastModifier="admin"
+ creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
@@ -280,12 +283,16 @@ under the License.
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<SyncopeGroup id="15" name="additional"
- realm_id="1"
+ realm_id="3"
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<TypeExtension id="1" group_id="15" anyType_name="USER"/>
<TypeExtension_AnyTypeClass typeExtension_id="1" anyTypeClass_name="csv"/>
<TypeExtension_AnyTypeClass typeExtension_id="1" anyTypeClass_name="other"/>
+ <SyncopeGroup id="16" name="fake"
+ realm_id="2"
+ creator="admin" lastModifier="admin"
+ creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GroupDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GroupDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GroupDataBinder.java
index d2ab1fa..62753f0 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GroupDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GroupDataBinder.java
@@ -29,7 +29,7 @@ public interface GroupDataBinder {
GroupTO getGroupTO(Group group, boolean details);
- Group create(Group group, GroupTO groupTO);
+ void create(Group group, GroupTO groupTO);
PropagationByResource update(Group group, GroupPatch groupPatch);
http://git-wip-us.apache.org/repos/asf/syncope/blob/bbb051fe/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 281fc69..3db4fc8 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -63,6 +63,7 @@ import org.apache.syncope.core.misc.utils.ConnObjectUtils;
import org.apache.syncope.core.misc.utils.MappingUtils;
import org.apache.syncope.core.misc.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
@@ -135,6 +136,9 @@ abstract class AbstractAnyDataBinder {
protected RelationshipTypeDAO relationshipTypeDAO;
@Autowired
+ protected AnySearchDAO searchDAO;
+
+ @Autowired
protected EntityFactory entityFactory;
@Autowired
@@ -431,11 +435,6 @@ abstract class AbstractAnyDataBinder {
scce.addException(requiredValuesMissing);
}
- // Throw composite exception if there is at least one element set in the composing exceptions
- if (scce.hasExceptions()) {
- throw scce;
- }
-
return propByRes;
}
@@ -488,15 +487,7 @@ abstract class AbstractAnyDataBinder {
scce.addException(requiredValuesMissing);
}
- // 2. realm & resources
- Realm realm = realmDAO.find(anyTO.getRealm());
- if (realm == null) {
- SyncopeClientException noRealm = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
- noRealm.getElements().add("Invalid or null realm specified: " + anyTO.getRealm());
- scce.addException(noRealm);
- }
- any.setRealm(realm);
-
+ // 2. resources
for (String resourceName : anyTO.getResources()) {
ExternalResource resource = resourceDAO.find(resourceName);
if (resource == null) {
@@ -510,11 +501,6 @@ abstract class AbstractAnyDataBinder {
if (!requiredValuesMissing.isEmpty()) {
scce.addException(requiredValuesMissing);
}
-
- // Throw composite exception if there is at least one element set in the composing exceptions
- if (scce.hasExceptions()) {
- throw scce;
- }
}
protected void fillTO(final AnyTO anyTO,