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 2017/05/08 11:40:19 UTC
[4/8] syncope git commit: [SYNCOPE-1077] Extension provided,
not enabled by default in fit/core-reference (profile available)
[SYNCOPE-1077] Extension provided, not enabled by default in fit/core-reference (profile available)
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/07e31980
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/07e31980
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/07e31980
Branch: refs/heads/2_0_X
Commit: 07e31980a076f1276ee2c3667bdcb00143ec2d52
Parents: a7b31ea
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon May 8 13:32:27 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon May 8 13:32:27 2017 +0200
----------------------------------------------------------------------
.../client/console/commons/Constants.java | 2 +-
.../client/enduser/resources/InfoResource.java | 2 -
.../enduser/resources/SchemaResource.java | 2 -
.../resources/UserSelfCreateResource.java | 2 -
.../enduser/resources/UserSelfReadResource.java | 2 -
.../syncope/common/lib/info/PlatformInfo.java | 10 +
.../apache/syncope/core/logic/SyncopeLogic.java | 9 +-
.../init/ClassPathScanImplementationLookup.java | 47 +--
.../core/logic/report/GroupReportlet.java | 23 +-
.../logic/report/ReconciliationReportlet.java | 9 +-
.../core/logic/report/UserReportlet.java | 23 +-
.../core/persistence/api/dao/AnyDAO.java | 15 +-
.../core/persistence/api/dao/AnyObjectDAO.java | 7 +-
.../core/persistence/api/dao/GroupDAO.java | 2 -
.../core/persistence/api/dao/UserDAO.java | 4 +-
core/persistence-jpa/pom.xml | 5 -
.../persistence/jpa/dao/AbstractAnyDAO.java | 11 +-
.../jpa/dao/AbstractAnySearchDAO.java | 343 ++++++++++++++++++
.../persistence/jpa/dao/JPAAnyObjectDAO.java | 45 ++-
.../persistence/jpa/dao/JPAAnySearchDAO.java | 354 ++++--------------
.../core/persistence/jpa/dao/JPAGroupDAO.java | 122 +++++--
.../core/persistence/jpa/dao/JPARoleDAO.java | 8 +
.../core/persistence/jpa/dao/JPAUserDAO.java | 17 +-
.../src/main/resources/persistence.properties | 1 +
.../src/main/resources/persistenceContext.xml | 1 +
.../persistence/jpa/inner/AnyObjectTest.java | 2 +-
.../core/persistence/jpa/inner/GroupTest.java | 2 +-
.../persistence/jpa/inner/MultitenancyTest.java | 2 +-
.../core/persistence/jpa/inner/UserTest.java | 3 +-
.../persistence/jpa/outer/AnySearchTest.java | 5 +-
.../core/persistence/jpa/outer/UserTest.java | 6 -
.../DefaultAnyObjectProvisioningManager.java | 2 +-
.../java/DefaultUserProvisioningManager.java | 6 +-
.../java/job/ExpiredAccessTokenCleanup.java | 4 +-
.../java/job/IdentityRecertification.java | 45 +--
.../AbstractPropagationTaskExecutor.java | 4 +-
.../propagation/PropagationManagerImpl.java | 2 +-
.../java/pushpull/PushJobDelegate.java | 19 +-
.../spring/event/AnyCreatedUpdatedEvent.java | 39 ++
.../core/spring/event/AnyDeletedEvent.java | 44 +++
core/workflow-activiti/pom.xml | 5 -
.../activiti/ActivitiUserWorkflowAdapter.java | 17 +-
.../activiti/SyncopeGroupQueryImpl.java | 21 +-
.../workflow/activiti/SyncopeUserQueryImpl.java | 21 +-
core/workflow-flowable/pom.xml | 5 -
.../flowable/FlowableUserWorkflowAdapter.java | 17 +-
.../flowable/SyncopeGroupQueryImpl.java | 21 +-
.../workflow/flowable/SyncopeUserQueryImpl.java | 21 +-
core/workflow-java/pom.xml | 5 +
.../java/AbstractAnyObjectWorkflowAdapter.java | 8 +
.../java/AbstractGroupWorkflowAdapter.java | 8 +
.../java/AbstractUserWorkflowAdapter.java | 34 +-
.../java/DefaultAnyObjectWorkflowAdapter.java | 2 +-
.../java/DefaultGroupWorkflowAdapter.java | 2 +-
.../java/DefaultUserWorkflowAdapter.java | 19 +-
.../camel/producer/DeleteProducer.java | 2 +-
.../camel/producer/DeprovisionProducer.java | 4 +-
ext/elasticsearch/client-elasticsearch/pom.xml | 61 ++++
.../client/ElasticsearchClientFactoryBean.java | 83 +++++
.../client/ElasticsearchIndexManager.java | 95 +++++
.../client/ElasticsearchUtils.java | 194 ++++++++++
.../resources/elasticsearchClientContext.xml | 50 +++
ext/elasticsearch/persistence-jpa/pom.xml | 62 ++++
.../jpa/dao/ElasticsearchAnySearchDAO.java | 355 +++++++++++++++++++
.../src/main/resources/persistence.properties | 18 +
ext/elasticsearch/pom.xml | 46 +++
ext/elasticsearch/provisioning-java/pom.xml | 62 ++++
.../java/job/ElasticsearchReindex.java | 137 +++++++
ext/pom.xml | 1 +
fit/core-reference/pom.xml | 72 ++++
.../core/reference/ITImplementationLookup.java | 40 ++-
.../elasticsearch/persistence.properties | 18 +
.../src/main/resources/elasticsearch/web.xml | 50 +++
.../src/main/resources/log4j2.xml | 10 +-
fit/core-reference/src/test/resources/rebel.xml | 9 +
pom.xml | 18 +-
76 files changed, 2293 insertions(+), 551 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
index 11bdc72..1eedd67 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java
@@ -45,7 +45,7 @@ public final class Constants {
public static final String USERNAME_FIELD_NAME = "username";
- public static final String OBJNAME_FIELD_NAME = "name";
+ public static final String NAME_FIELD_NAME = "name";
public static final String DEFAULT_TOKEN_FIELD_NAME = "token";
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
index c96fa2a..23af8fc 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.client.enduser.resources;
-import static org.apache.syncope.client.enduser.resources.BaseResource.MAPPER;
-
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index 5edd4b0..b088201 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.client.enduser.resources;
-import static org.apache.syncope.client.enduser.resources.BaseResource.MAPPER;
-
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
index b7775b1..8b42285 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.client.enduser.resources;
-import static org.apache.syncope.client.enduser.resources.BaseResource.LOG;
-
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
index 81ffcd1..c4cb6c1 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.client.enduser.resources;
-import static org.apache.syncope.client.enduser.resources.BaseResource.MAPPER;
-
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
index 1f3cbd1..9a7ac61 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/info/PlatformInfo.java
@@ -65,6 +65,8 @@ public class PlatformInfo extends AbstractBaseBean {
private String passwordGenerator;
+ private String anySearchDAO;
+
private final Set<String> entitlements = new HashSet<>();
private final Set<String> reportletConfs = new HashSet<>();
@@ -166,6 +168,14 @@ public class PlatformInfo extends AbstractBaseBean {
this.passwordGenerator = passwordGenerator;
}
+ public String getAnySearchDAO() {
+ return anySearchDAO;
+ }
+
+ public void setAnySearchDAO(final String anySearchDAO) {
+ this.anySearchDAO = anySearchDAO;
+ }
+
@XmlElementWrapper(name = "entitlements")
@XmlElement(name = "entitlement")
@JsonProperty("entitlements")
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
index 36cc50c..bce3c09 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/SyncopeLogic.java
@@ -38,6 +38,7 @@ import org.apache.syncope.core.spring.security.PasswordGenerator;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
import org.apache.syncope.core.persistence.api.ImplementationLookup.Type;
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.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -139,6 +140,9 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
private PasswordGenerator passwordGenerator;
@Autowired
+ private AnySearchDAO anySearchDAO;
+
+ @Autowired
private ImplementationLookup implLookup;
public boolean isSelfRegAllowed() {
@@ -176,8 +180,9 @@ public class SyncopeLogic extends AbstractLogic<AbstractBaseBean> {
PLATFORM_INFO.setAnyObjectProvisioningManager(AopUtils.getTargetClass(aProvisioningManager).getName());
PLATFORM_INFO.setUserProvisioningManager(AopUtils.getTargetClass(uProvisioningManager).getName());
PLATFORM_INFO.setGroupProvisioningManager(AopUtils.getTargetClass(gProvisioningManager).getName());
- PLATFORM_INFO.setVirAttrCache(virAttrCache.getClass().getName());
- PLATFORM_INFO.setPasswordGenerator(passwordGenerator.getClass().getName());
+ PLATFORM_INFO.setVirAttrCache(AopUtils.getTargetClass(virAttrCache).getName());
+ PLATFORM_INFO.setPasswordGenerator(AopUtils.getTargetClass(passwordGenerator).getName());
+ PLATFORM_INFO.setAnySearchDAO(AopUtils.getTargetClass(anySearchDAO).getName());
PLATFORM_INFO.getReportletConfs().addAll(implLookup.getClassNames(Type.REPORTLET_CONF));
PLATFORM_INFO.getAccountRules().addAll(implLookup.getClassNames(Type.ACCOUNT_RULE_CONF));
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
index b91f2aa..3799150 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java
@@ -28,34 +28,35 @@ import java.util.Set;
import org.apache.syncope.common.lib.policy.AccountRuleConf;
import org.apache.syncope.common.lib.policy.PasswordRuleConf;
import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.core.persistence.api.dao.Reportlet;
-import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.ImplementationLookup.Type;
import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
import org.apache.syncope.core.persistence.api.dao.AccountRule;
import org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass;
import org.apache.syncope.core.persistence.api.dao.PasswordRule;
import org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass;
+import org.apache.syncope.core.persistence.api.dao.Reportlet;
+import org.apache.syncope.core.persistence.api.dao.ReportletConfClass;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.provisioning.api.data.MappingItemTransformer;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider;
import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
+import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
import org.apache.syncope.core.provisioning.api.pushpull.PushActions;
-import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
+import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
+import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
+import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PlainAttrsPullCorrelationRule;
import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate;
+import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.util.ClassUtils;
-import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder;
-import org.apache.syncope.core.provisioning.api.pushpull.PullCorrelationRule;
-import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
-import org.apache.syncope.core.provisioning.java.data.JEXLMappingItemTransformerImpl;
-import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate;
-import org.apache.syncope.core.provisioning.java.pushpull.PlainAttrsPullCorrelationRule;
/**
* Cache class names for all implementations of Syncope interfaces found in classpath, for later usage.
@@ -119,9 +120,9 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
try {
Class<?> clazz = ClassUtils.resolveClassName(
bd.getBeanClassName(), ClassUtils.getDefaultClassLoader());
- boolean isAbsractClazz = Modifier.isAbstract(clazz.getModifiers());
+ boolean isAbstractClazz = Modifier.isAbstract(clazz.getModifiers());
- if (Reportlet.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (Reportlet.class.isAssignableFrom(clazz) && !isAbstractClazz) {
ReportletConfClass annotation = clazz.getAnnotation(ReportletConfClass.class);
if (annotation == null) {
LOG.warn("Found Reportlet {} without declared configuration", clazz.getName());
@@ -131,7 +132,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
}
}
- if (AccountRule.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (AccountRule.class.isAssignableFrom(clazz) && !isAbstractClazz) {
AccountRuleConfClass annotation = clazz.getAnnotation(AccountRuleConfClass.class);
if (annotation == null) {
LOG.warn("Found account policy rule {} without declared configuration", clazz.getName());
@@ -141,7 +142,7 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
}
}
- if (PasswordRule.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (PasswordRule.class.isAssignableFrom(clazz) && !isAbstractClazz) {
PasswordRuleConfClass annotation = clazz.getAnnotation(PasswordRuleConfClass.class);
if (annotation == null) {
LOG.warn("Found password policy rule {} without declared configuration", clazz.getName());
@@ -151,13 +152,13 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
}
}
- if (MappingItemTransformer.class.isAssignableFrom(clazz) && !isAbsractClazz
+ if (MappingItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz
&& !clazz.equals(JEXLMappingItemTransformerImpl.class)) {
classNames.get(Type.MAPPING_ITEM_TRANSFORMER).add(clazz.getName());
}
- if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbsractClazz
+ if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbstractClazz
&& !PullJobDelegate.class.isAssignableFrom(clazz)
&& !PushJobDelegate.class.isAssignableFrom(clazz)
&& !GroupMemberProvisionTaskJobDelegate.class.isAssignableFrom(clazz)) {
@@ -165,36 +166,36 @@ public class ClassPathScanImplementationLookup implements ImplementationLookup {
classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
}
- if (ReconciliationFilterBuilder.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (ReconciliationFilterBuilder.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.RECONCILIATION_FILTER_BUILDER).add(bd.getBeanClassName());
}
- if (LogicActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (LogicActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.LOGIC_ACTIONS).add(bd.getBeanClassName());
}
- if (PropagationActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (PropagationActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.PROPAGATION_ACTIONS).add(bd.getBeanClassName());
}
- if (PullActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (PullActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.PULL_ACTIONS).add(bd.getBeanClassName());
}
- if (PushActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (PushActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.PUSH_ACTIONS).add(bd.getBeanClassName());
}
- if (PullCorrelationRule.class.isAssignableFrom(clazz) && !isAbsractClazz
+ if (PullCorrelationRule.class.isAssignableFrom(clazz) && !isAbstractClazz
&& !PlainAttrsPullCorrelationRule.class.isAssignableFrom(clazz)) {
classNames.get(Type.PULL_CORRELATION_RULE).add(bd.getBeanClassName());
}
- if (Validator.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (Validator.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.VALIDATOR).add(bd.getBeanClassName());
}
- if (NotificationRecipientsProvider.class.isAssignableFrom(clazz) && !isAbsractClazz) {
+ if (NotificationRecipientsProvider.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(Type.NOTIFICATION_RECIPIENTS_PROVIDER).add(bd.getBeanClassName());
}
} catch (Throwable t) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
index 4bc4a37..0aeaf0a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/GroupReportlet.java
@@ -31,6 +31,7 @@ import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -47,8 +48,6 @@ import org.xml.sax.helpers.AttributesImpl;
@ReportletConfClass(GroupReportletConf.class)
public class GroupReportlet extends AbstractReportlet {
- private static final int PAGE_SIZE = 10;
-
@Autowired
private GroupDAO groupDAO;
@@ -297,15 +296,21 @@ public class GroupReportlet extends AbstractReportlet {
doExtractConf(handler);
- if (StringUtils.isBlank(this.conf.getMatchingCond())) {
- doExtract(handler, groupDAO.findAll());
- } else {
- for (int page = 1; page <= (count() / PAGE_SIZE) + 1; page++) {
- List<Group> groups = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ for (int page = 1; page <= (count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+ List<Group> groups;
+ if (StringUtils.isBlank(this.conf.getMatchingCond())) {
+ groups = groupDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE);
+ } else {
+ groups = searchDAO.search(
+ SyncopeConstants.FULL_ADMIN_REALMS,
SearchCondConverter.convert(this.conf.getMatchingCond()),
- page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), AnyTypeKind.GROUP);
- doExtract(handler, groups);
+ page,
+ AnyDAO.DEFAULT_PAGE_SIZE,
+ Collections.<OrderByClause>emptyList(),
+ AnyTypeKind.USER);
}
+
+ doExtract(handler, groups);
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
index ac5c1f1..4922015 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReconciliationReportlet.java
@@ -35,6 +35,7 @@ import org.apache.syncope.common.lib.report.ReconciliationReportletConf;
import org.apache.syncope.common.lib.report.ReconciliationReportletConf.Feature;
import org.apache.syncope.common.lib.report.ReportletConf;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
@@ -402,7 +403,9 @@ public class ReconciliationReportlet extends AbstractReportlet {
atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(userDAO.count()));
handler.startElement("", "", getAnyElementName(AnyTypeKind.USER) + "s", atts);
- doExtract(handler, userDAO.findAll());
+ for (int page = 1; page <= (userDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+ doExtract(handler, userDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE));
+ }
} else {
SearchCond cond = SearchCondConverter.convert(this.conf.getUserMatchingCond());
@@ -419,7 +422,9 @@ public class ReconciliationReportlet extends AbstractReportlet {
atts.addAttribute("", "", "total", ReportXMLConst.XSD_INT, String.valueOf(groupDAO.count()));
handler.startElement("", "", getAnyElementName(AnyTypeKind.GROUP) + "s", atts);
- doExtract(handler, groupDAO.findAll());
+ for (int page = 1; page <= (groupDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+ doExtract(handler, groupDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE));
+ }
} else {
SearchCond cond = SearchCondConverter.convert(this.conf.getUserMatchingCond());
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
index 38fba8a..bb1048b 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/UserReportlet.java
@@ -33,6 +33,7 @@ import org.apache.syncope.common.lib.to.MembershipTO;
import org.apache.syncope.common.lib.to.RelationshipTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -53,8 +54,6 @@ import org.xml.sax.helpers.AttributesImpl;
@ReportletConfClass(UserReportletConf.class)
public class UserReportlet extends AbstractReportlet {
- private static final int PAGE_SIZE = 10;
-
@Autowired
private UserDAO userDAO;
@@ -364,15 +363,21 @@ public class UserReportlet extends AbstractReportlet {
doExtractConf(handler);
- if (StringUtils.isBlank(this.conf.getMatchingCond())) {
- doExtract(handler, userDAO.findAll());
- } else {
- for (int page = 1; page <= (count() / PAGE_SIZE) + 1; page++) {
- List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+ for (int page = 1; page <= (count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+ List<User> users;
+ if (StringUtils.isBlank(this.conf.getMatchingCond())) {
+ users = userDAO.findAll(page, AnyDAO.DEFAULT_PAGE_SIZE);
+ } else {
+ users = searchDAO.search(
+ SyncopeConstants.FULL_ADMIN_REALMS,
SearchCondConverter.convert(this.conf.getMatchingCond()),
- page, PAGE_SIZE, Collections.<OrderByClause>emptyList(), AnyTypeKind.USER);
- doExtract(handler, users);
+ page,
+ AnyDAO.DEFAULT_PAGE_SIZE,
+ Collections.<OrderByClause>emptyList(),
+ AnyTypeKind.USER);
}
+
+ doExtract(handler, users);
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
index 6b2fd4e..44c0c8c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
@@ -28,6 +28,8 @@ import org.apache.syncope.core.persistence.api.entity.Schema;
public interface AnyDAO<A extends Any<?>> extends DAO<A> {
+ int DEFAULT_PAGE_SIZE = 10;
+
A authFind(String key);
A find(String key);
@@ -53,11 +55,18 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> {
List<A> findByResource(ExternalResource resource);
/**
- * Find any objects without any limitation.
+ * @return the total number of any objects of type {@link A}
+ */
+ int count();
+
+ /**
+ * Find any objects without any limitation, according to given page and items per page.
*
- * @return all any objects of type {@link A} available.
+ * @param page search result page
+ * @param itemsPerPage items per search result page
+ * @return any objects of type {@link A} matching the provided conditions
*/
- List<A> findAll();
+ List<A> findAll(int page, int itemsPerPage);
/**
* Find any objects visible from the given admin realms, according to given page and items per page, sorted as
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index d399ac8..c3a4cd7 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -26,7 +26,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
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.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.user.URelationship;
public interface AnyObjectDAO extends AnyDAO<AnyObject> {
@@ -46,9 +45,7 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
List<Group> findDynGroupMemberships(AnyObject anyObject);
- List<ARelationship> findARelationships(AnyObject anyObject);
-
- List<URelationship> findURelationships(AnyObject anyObject);
+ List<ARelationship> findAllARelationships(AnyObject anyObject);
Collection<Group> findAllGroups(AnyObject anyObject);
@@ -56,5 +53,5 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
Collection<ExternalResource> findAllResources(AnyObject anyObject);
- Collection<String> findAllResourceNames(String key);
+ Collection<String> findAllResourceKeys(String key);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
index aa30108..c74e430 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GroupDAO.java
@@ -30,8 +30,6 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
public interface GroupDAO extends AnyDAO<Group> {
- int count();
-
Map<String, Integer> countByRealm();
Group findByName(String name);
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index d577327..55efa93 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -30,8 +30,6 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
public interface UserDAO extends AnyDAO<User> {
- int count();
-
Map<String, Integer> countByRealm();
Map<String, Integer> countByStatus();
@@ -58,7 +56,7 @@ public interface UserDAO extends AnyDAO<User> {
Collection<ExternalResource> findAllResources(User user);
- Collection<String> findAllResourceNames(String key);
+ Collection<String> findAllResourceKeys(String key);
Pair<Boolean, Boolean> enforcePolicies(User user);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index b97cca3..87d0efe 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -98,11 +98,6 @@ under the License.
</dependency>
<dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- </dependency>
-
- <dependency>
<groupId>org.apache.syncope.core</groupId>
<artifactId>syncope-core-workflow-api</artifactId>
<version>${project.version}</version>
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index 25bfe50..f348a06 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -36,7 +36,6 @@ import org.apache.commons.jexl3.parser.Parser;
import org.apache.commons.jexl3.parser.ParserConstants;
import org.apache.commons.jexl3.parser.Token;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.core.persistence.api.dao.AllowedSchemas;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
@@ -64,11 +63,16 @@ import org.apache.syncope.core.persistence.api.entity.user.UMembership;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> implements AnyDAO<A> {
+ @Autowired
+ protected ApplicationEventPublisher publisher;
+
private PlainSchemaDAO plainSchemaDAO;
private DerSchemaDAO derSchemaDAO;
@@ -425,11 +429,6 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
return query.getResultList();
}
- @Override
- public final List<A> findAll() {
- return findAll(SyncopeConstants.FULL_ADMIN_REALMS, -1, -1, Collections.<OrderByClause>emptyList());
- }
-
private SearchCond getAllMatchingCond() {
AnyCond idCond = new AnyCond(AttributeCond.Type.ISNOTNULL);
idCond.setSchema("id");
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
new file mode 100644
index 0000000..d9b4e95
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -0,0 +1,343 @@
+/*
+ * 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.jpa.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Entity;
+import javax.validation.ValidationException;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.Triple;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+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.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AssignableCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MemberCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+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;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+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.jpa.entity.JPAPlainSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ReflectionUtils;
+
+public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO {
+
+ @Autowired
+ protected RealmDAO realmDAO;
+
+ @Autowired
+ protected AnyObjectDAO anyObjectDAO;
+
+ @Autowired
+ protected UserDAO userDAO;
+
+ @Autowired
+ protected GroupDAO groupDAO;
+
+ @Autowired
+ protected PlainSchemaDAO schemaDAO;
+
+ @Autowired
+ protected AnyUtilsFactory anyUtilsFactory;
+
+ @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);
+ }
+
+ protected abstract int doCount(Set<String> adminRealms, SearchCond cond, AnyTypeKind kind);
+
+ @Override
+ public int count(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind kind) {
+ if (adminRealms == null || adminRealms.isEmpty()) {
+ LOG.error("No realms provided");
+ return 0;
+ }
+
+ LOG.debug("Search condition:\n{}", cond);
+ if (cond == null || !cond.isValid()) {
+ LOG.error("Invalid search condition:\n{}", cond);
+ return 0;
+ }
+
+ return doCount(adminRealms, cond, kind);
+ }
+
+ @Override
+ public <T extends Any<?>> List<T> search(final SearchCond cond, final AnyTypeKind kind) {
+ return search(cond, Collections.<OrderByClause>emptyList(), kind);
+ }
+
+ @Override
+ public <T extends Any<?>> List<T> search(
+ final SearchCond cond, final List<OrderByClause> orderBy, final AnyTypeKind kind) {
+
+ return search(SyncopeConstants.FULL_ADMIN_REALMS, cond, -1, -1, orderBy, kind);
+ }
+
+ protected abstract <T extends Any<?>> List<T> doSearch(
+ Set<String> adminRealms,
+ SearchCond searchCondition,
+ int page,
+ int itemsPerPage,
+ List<OrderByClause> orderBy,
+ AnyTypeKind kind);
+
+ protected Pair<PlainSchema, PlainAttrValue> check(final AttributeCond cond, final AnyTypeKind kind) {
+ AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
+
+ PlainSchema schema = schemaDAO.find(cond.getSchema());
+ if (schema == null) {
+ LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
+ throw new IllegalArgumentException();
+ }
+
+ PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+ try {
+ if (cond.getType() != AttributeCond.Type.LIKE
+ && cond.getType() != AttributeCond.Type.ILIKE
+ && cond.getType() != AttributeCond.Type.ISNULL
+ && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+
+ schema.getValidator().validate(cond.getExpression(), attrValue);
+ }
+ } catch (ValidationException e) {
+ LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+ throw new IllegalArgumentException();
+ }
+
+ return Pair.of(schema, attrValue);
+ }
+
+ protected Triple<PlainSchema, PlainAttrValue, AnyCond> check(final AnyCond cond, final AnyTypeKind kind) {
+ AnyCond condClone = SerializationUtils.clone(cond);
+
+ AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
+
+ // Keeps track of difference between entity's getKey() and JPA @Id fields
+ if ("key".equals(condClone.getSchema())) {
+ condClone.setSchema("id");
+ }
+
+ Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), condClone.getSchema());
+ if (anyField == null) {
+ LOG.warn("Ignoring invalid schema '{}'", condClone.getSchema());
+ throw new IllegalArgumentException();
+ }
+
+ PlainSchema schema = new JPAPlainSchema();
+ schema.setKey(anyField.getName());
+ for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
+ if (anyField.getType().isAssignableFrom(attrSchemaType.getType())) {
+ schema.setType(attrSchemaType);
+ }
+ }
+
+ // Deal with any Integer fields logically mapping to boolean values
+ boolean foundBooleanMin = false;
+ boolean foundBooleanMax = false;
+ if (Integer.class.equals(anyField.getType())) {
+ for (Annotation annotation : anyField.getAnnotations()) {
+ if (Min.class.equals(annotation.annotationType())) {
+ foundBooleanMin = ((Min) annotation).value() == 0;
+ } else if (Max.class.equals(annotation.annotationType())) {
+ foundBooleanMax = ((Max) annotation).value() == 1;
+ }
+ }
+ }
+ if (foundBooleanMin && foundBooleanMax) {
+ schema.setType(AttrSchemaType.Boolean);
+ }
+
+ // Deal with any fields representing relationships to other entities
+ if (anyField.getType().getAnnotation(Entity.class) != null) {
+ Method relMethod = null;
+ try {
+ relMethod = ClassUtils.getPublicMethod(anyField.getType(), "getKey", new Class<?>[0]);
+ } catch (Exception e) {
+ LOG.error("Could not find {}#getKey", anyField.getType(), e);
+ }
+
+ if (relMethod != null && String.class.isAssignableFrom(relMethod.getReturnType())) {
+ condClone.setSchema(condClone.getSchema() + "_id");
+ schema.setType(AttrSchemaType.String);
+ }
+ }
+
+ PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+ if (condClone.getType() != AttributeCond.Type.LIKE
+ && condClone.getType() != AttributeCond.Type.ILIKE
+ && condClone.getType() != AttributeCond.Type.ISNULL
+ && condClone.getType() != AttributeCond.Type.ISNOTNULL) {
+
+ try {
+ schema.getValidator().validate(condClone.getExpression(), attrValue);
+ } catch (ValidationException e) {
+ LOG.error("Could not validate expression '" + condClone.getExpression() + "'", e);
+ throw new IllegalArgumentException();
+ }
+ }
+
+ return Triple.of(schema, attrValue, condClone);
+ }
+
+ protected String check(final MembershipCond cond) {
+ String groupKey;
+ if (SyncopeConstants.UUID_PATTERN.matcher(cond.getGroup()).matches()) {
+ groupKey = cond.getGroup();
+ } else {
+ Group group = groupDAO.findByName(cond.getGroup());
+ groupKey = group == null ? null : group.getKey();
+ }
+ if (groupKey == null) {
+ LOG.error("Could not find group for '" + cond.getGroup() + "'");
+ throw new IllegalArgumentException();
+ }
+
+ return groupKey;
+ }
+
+ protected String check(final RelationshipCond cond) {
+ String rightAnyObjectKey;
+ if (SyncopeConstants.UUID_PATTERN.matcher(cond.getAnyObject()).matches()) {
+ rightAnyObjectKey = cond.getAnyObject();
+ } else {
+ AnyObject anyObject = anyObjectDAO.findByName(cond.getAnyObject());
+ rightAnyObjectKey = anyObject == null ? null : anyObject.getKey();
+ }
+ if (rightAnyObjectKey == null) {
+ LOG.error("Could not find any object for '" + cond.getAnyObject() + "'");
+ throw new IllegalArgumentException();
+ }
+
+ return rightAnyObjectKey;
+ }
+
+ protected Realm check(final AssignableCond cond) {
+ Realm realm = realmDAO.findByFullPath(cond.getRealmFullPath());
+ if (realm == null) {
+ LOG.error("Could not find realm for '" + cond.getRealmFullPath() + "'");
+ throw new IllegalArgumentException();
+ }
+
+ return realm;
+ }
+
+ protected String check(final MemberCond cond) {
+ String memberKey;
+ if (SyncopeConstants.UUID_PATTERN.matcher(cond.getMember()).matches()) {
+ memberKey = cond.getMember();
+ } else {
+ Any<?> member = userDAO.findByUsername(cond.getMember());
+ if (member == null) {
+ member = anyObjectDAO.findByName(cond.getMember());
+ }
+ memberKey = member == null ? null : member.getKey();
+ }
+ if (memberKey == null) {
+ LOG.error("Could not find user or any object for '" + cond.getMember() + "'");
+ throw new IllegalArgumentException();
+ }
+
+ return memberKey;
+ }
+
+ protected <T extends Any<?>> List<T> buildResult(final List<Object> raw, final AnyTypeKind kind) {
+ List<T> result = new ArrayList<>();
+
+ for (Object anyKey : raw) {
+ String actualKey = anyKey instanceof Object[]
+ ? (String) ((Object[]) anyKey)[0]
+ : ((String) anyKey);
+
+ @SuppressWarnings("unchecked")
+ T any = kind == AnyTypeKind.USER
+ ? (T) userDAO.find(actualKey)
+ : kind == AnyTypeKind.GROUP
+ ? (T) groupDAO.find(actualKey)
+ : (T) anyObjectDAO.find(actualKey);
+ if (any == null) {
+ LOG.error("Could not find {} with id {}, even if returned by native query", kind, actualKey);
+ } else if (!result.contains(any)) {
+ result.add(any);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public <T extends Any<?>> List<T> search(
+ final Set<String> adminRealms,
+ final SearchCond cond,
+ final int page,
+ final int itemsPerPage,
+ final List<OrderByClause> orderBy,
+ final AnyTypeKind kind) {
+
+ if (adminRealms == null || adminRealms.isEmpty()) {
+ LOG.error("No realms provided");
+ return Collections.<T>emptyList();
+ }
+
+ LOG.debug("Search condition:\n{}", cond);
+ if (cond == null || !cond.isValid()) {
+ LOG.error("Invalid search condition:\n{}", cond);
+ return Collections.<T>emptyList();
+ }
+
+ return doSearch(adminRealms, cond, page, itemsPerPage, orderBy, kind);
+ }
+
+ @Override
+ public <T extends Any<?>> boolean matches(final T any, final SearchCond cond) {
+ return search(cond, any.getType().getKind()).contains(any);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index 164f9a3..a64afe3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -59,6 +59,8 @@ import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.event.AnyCreatedUpdatedEvent;
+import org.apache.syncope.core.spring.event.AnyDeletedEvent;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -175,21 +177,28 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
@Override
- public List<ARelationship> findARelationships(final AnyObject anyObject) {
+ public List<ARelationship> findAllARelationships(final AnyObject anyObject) {
TypedQuery<ARelationship> query = entityManager().createQuery(
"SELECT e FROM " + JPAARelationship.class.getSimpleName()
- + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
+ + " e WHERE e.rightEnd=:anyObject OR e.leftEnd=:anyObject", ARelationship.class);
query.setParameter("anyObject", anyObject);
return query.getResultList();
}
@Override
- public List<URelationship> findURelationships(final AnyObject anyObject) {
- TypedQuery<URelationship> query = entityManager().createQuery(
- "SELECT e FROM " + JPAURelationship.class.getSimpleName()
- + " e WHERE e.rightEnd=:anyObject", URelationship.class);
- query.setParameter("anyObject", anyObject);
+ public int count() {
+ Query query = entityManager().createQuery(
+ "SELECT COUNT(e) FROM " + JPAAnyObject.class.getSimpleName() + " e");
+ return ((Number) query.getSingleResult()).intValue();
+ }
+
+ @Override
+ public List<AnyObject> findAll(final int page, final int itemsPerPage) {
+ TypedQuery<AnyObject> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAAnyObject.class.getSimpleName() + " e", AnyObject.class);
+ query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+ query.setMaxResults(itemsPerPage);
return query.getResultList();
}
@@ -197,12 +206,31 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
@Override
public AnyObject save(final AnyObject anyObject) {
AnyObject merged = super.save(anyObject);
+ publisher.publishEvent(new AnyCreatedUpdatedEvent<>(this, merged));
groupDAO().refreshDynMemberships(merged);
return merged;
}
+ private List<ARelationship> findARelationships(final AnyObject anyObject) {
+ TypedQuery<ARelationship> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAARelationship.class.getSimpleName()
+ + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
+ query.setParameter("anyObject", anyObject);
+
+ return query.getResultList();
+ }
+
+ private List<URelationship> findURelationships(final AnyObject anyObject) {
+ TypedQuery<URelationship> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAURelationship.class.getSimpleName()
+ + " e WHERE e.rightEnd=:anyObject", URelationship.class);
+ query.setParameter("anyObject", anyObject);
+
+ return query.getResultList();
+ }
+
@Override
public void delete(final AnyObject any) {
for (Group group : findDynGroupMemberships(any)) {
@@ -223,6 +251,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
}
entityManager().remove(any);
+ publisher.publishEvent(new AnyDeletedEvent(this, AnyTypeKind.ANY_OBJECT, any.getKey()));
}
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@@ -287,7 +316,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
@Override
- public Collection<String> findAllResourceNames(final String key) {
+ public Collection<String> findAllResourceKeys(final String key) {
return CollectionUtils.collect(findAllResources(authFind(key)), EntityUtils.<ExternalResource>keyTransformer());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/07e31980/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 49bf4ff..276b570 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
@@ -18,36 +18,23 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import javax.persistence.Entity;
import javax.persistence.Query;
import javax.persistence.TemporalType;
-import javax.validation.ValidationException;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.lang3.tuple.Triple;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-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.AnySearchDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -62,42 +49,18 @@ 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;
import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.persistence.api.entity.Realm;
-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.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<?>> implements AnySearchDAO {
+/**
+ * Search engine implementation for users, groups and any objects, based on self-updating SQL views.
+ */
+public class JPAAnySearchDAO extends AbstractAnySearchDAO {
private static final String EMPTY_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
- @Autowired
- private RealmDAO realmDAO;
-
- @Autowired
- private AnyObjectDAO anyObjectDAO;
-
- @Autowired
- private UserDAO userDAO;
-
- @Autowired
- private GroupDAO groupDAO;
-
- @Autowired
- private PlainSchemaDAO schemaDAO;
-
- @Autowired
- private AnyUtilsFactory anyUtilsFactory;
-
private String getAdminRealmsFilter(
final Set<String> adminRealms,
final SearchSupport svs,
@@ -135,11 +98,11 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
}
@Override
- public int count(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind typeKind) {
+ protected int doCount(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind kind) {
List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
// 1. get the query string from the search condition
- SearchSupport svs = new SearchSupport(typeKind);
+ SearchSupport svs = new SearchSupport(kind);
StringBuilder queryString = getQuery(cond, parameters, svs);
// 2. take into account administrative realms
@@ -156,78 +119,56 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
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 cond, final AnyTypeKind typeKind) {
- return search(cond, Collections.<OrderByClause>emptyList(), typeKind);
- }
-
@Override
- public <T extends Any<?>> List<T> search(
- final SearchCond cond, final List<OrderByClause> orderBy, final AnyTypeKind typeKind) {
-
- return search(SyncopeConstants.FULL_ADMIN_REALMS, cond, -1, -1, orderBy, typeKind);
- }
-
- @Override
- public <T extends Any<?>> List<T> search(
- final Set<String> adminRealms, final SearchCond cond, final int page, final int itemsPerPage,
- final List<OrderByClause> orderBy, final AnyTypeKind typeKind) {
+ @SuppressWarnings("unchecked")
+ protected <T extends Any<?>> List<T> doSearch(
+ final Set<String> adminRealms,
+ final SearchCond cond,
+ final int page,
+ final int itemsPerPage,
+ final List<OrderByClause> orderBy,
+ final AnyTypeKind kind) {
- List<T> result = Collections.<T>emptyList();
+ try {
+ List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
- if (adminRealms != null && !adminRealms.isEmpty()) {
- LOG.debug("Search condition:\n{}", cond);
+ // 1. get the query string from the search condition
+ SearchSupport svs = new SearchSupport(kind);
+ StringBuilder queryString = getQuery(cond, parameters, svs);
- if (cond != null && cond.isValid()) {
- try {
- result = doSearch(adminRealms, cond, page, itemsPerPage, orderBy, typeKind);
- } catch (Exception e) {
- LOG.error("While searching for {}", typeKind, e);
- }
+ // 2. take into account realms and ordering
+ OrderBySupport obs = parseOrderBy(kind, svs, orderBy);
+ if (queryString.charAt(0) == '(') {
+ queryString.insert(0, buildSelect(obs));
+ queryString.append(buildWhere(svs, obs));
} else {
- LOG.error("Invalid search condition:\n{}", cond);
+ queryString.insert(0, buildSelect(obs).append('('));
+ queryString.append(')').append(buildWhere(svs, obs));
}
- }
-
- return result;
- }
-
- @Override
- public <T extends Any<?>> boolean matches(final T any, final SearchCond cond) {
- List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
-
- // 1. get the query string from the search condition
- SearchSupport svs = new SearchSupport(any.getType().getKind());
- StringBuilder queryString = getQuery(cond, parameters, svs);
-
- boolean matches;
- if (queryString.length() == 0) {
- // Could be empty: got into a group search with a single membership condition ...
- matches = false;
- } else {
- // 2. take into account the passed user
- queryString.insert(0, "SELECT u.any_id FROM (");
- queryString.append(") u WHERE any_id=?").append(setParameter(parameters, any.getKey()));
+ queryString.
+ append(getAdminRealmsFilter(adminRealms, svs, parameters)).
+ append(buildOrderBy(obs));
// 3. prepare the search query
Query query = entityManager().createNativeQuery(queryString.toString());
- // 4. populate the search query with parameter values
+ // 4. page starts from 1, while setFirtResult() starts from 0
+ query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+
+ if (itemsPerPage >= 0) {
+ query.setMaxResults(itemsPerPage);
+ }
+
+ // 5. populate the search query with parameter values
fillWithParameters(query, parameters);
- // 5. executes query
- matches = !query.getResultList().isEmpty();
+ // 6. Prepare the result (avoiding duplicates)
+ return buildResult(query.getResultList(), kind);
+ } catch (Exception e) {
+ LOG.error("While searching for {}", kind, e);
}
- return matches;
+ return Collections.emptyList();
}
private int setParameter(final List<Object> parameters, final Object parameter) {
@@ -370,67 +311,6 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
return obs;
}
- @SuppressWarnings("unchecked")
- private <T extends Any<?>> List<T> doSearch(final Set<String> adminRealms,
- final SearchCond cond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy,
- final AnyTypeKind typeKind) {
-
- List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
-
- // 1. get the query string from the search condition
- SearchSupport svs = new SearchSupport(typeKind);
- StringBuilder queryString = getQuery(cond, parameters, svs);
-
- // 2. take into account administrative groups and ordering
- OrderBySupport obs = parseOrderBy(typeKind, svs, orderBy);
- if (queryString.charAt(0) == '(') {
- queryString.insert(0, buildSelect(obs));
- queryString.append(buildWhere(svs, obs));
- } else {
- queryString.insert(0, buildSelect(obs).append('('));
- queryString.append(')').append(buildWhere(svs, obs));
- }
- queryString.
- append(getAdminRealmsFilter(adminRealms, svs, parameters)).
- append(buildOrderBy(obs));
-
- // 3. prepare the search query
- Query query = entityManager().createNativeQuery(queryString.toString());
-
- // 4. page starts from 1, while setFirtResult() starts from 0
- query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
-
- if (itemsPerPage >= 0) {
- query.setMaxResults(itemsPerPage);
- }
-
- // 5. populate the search query with parameter values
- fillWithParameters(query, parameters);
-
- // 6. Prepare the result (avoiding duplicates)
- List<T> result = new ArrayList<>();
-
- for (Object anyKey : query.getResultList()) {
- String actualKey = anyKey instanceof Object[]
- ? (String) ((Object[]) anyKey)[0]
- : ((String) anyKey);
-
- T any = typeKind == AnyTypeKind.USER
- ? (T) userDAO.find(actualKey)
- : typeKind == AnyTypeKind.GROUP
- ? (T) groupDAO.find(actualKey)
- : (T) anyObjectDAO.find(actualKey);
- if (any == null) {
- LOG.error("Could not find {} with id {}, even though returned by the native query",
- typeKind, actualKey);
- } else if (!result.contains(any)) {
- result.add(any);
- }
- }
-
- return result;
- }
-
private StringBuilder getQuery(final SearchCond cond, final List<Object> parameters, final SearchSupport svs) {
StringBuilder query = new StringBuilder();
@@ -548,13 +428,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
final RelationshipCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
String rightAnyObjectKey;
- if (SyncopeConstants.UUID_PATTERN.matcher(cond.getAnyObject()).matches()) {
- rightAnyObjectKey = cond.getAnyObject();
- } else {
- AnyObject anyObject = anyObjectDAO.findByName(cond.getAnyObject());
- rightAnyObjectKey = anyObject == null ? null : anyObject.getKey();
- }
- if (rightAnyObjectKey == null) {
+ try {
+ rightAnyObjectKey = check(cond);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
@@ -579,13 +455,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
final MembershipCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
String groupKey;
- if (SyncopeConstants.UUID_PATTERN.matcher(cond.getGroup()).matches()) {
- groupKey = cond.getGroup();
- } else {
- Group group = groupDAO.findByName(cond.getGroup());
- groupKey = group == null ? null : group.getKey();
- }
- if (groupKey == null) {
+ try {
+ groupKey = check(cond);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
@@ -678,8 +550,10 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
}
private String getQuery(final AssignableCond cond, final List<Object> parameters, final SearchSupport svs) {
- Realm realm = realmDAO.findByFullPath(cond.getRealmFullPath());
- if (realm == null) {
+ Realm realm;
+ try {
+ realm = check(cond);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
@@ -705,16 +579,9 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
final MemberCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
String memberKey;
- if (SyncopeConstants.UUID_PATTERN.matcher(cond.getMember()).matches()) {
- memberKey = cond.getMember();
- } else {
- Any<?> member = userDAO.findByUsername(cond.getMember());
- if (member == null) {
- member = anyObjectDAO.findByName(cond.getMember());
- }
- memberKey = member == null ? null : member.getKey();
- }
- if (memberKey == null) {
+ try {
+ memberKey = check(cond);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
@@ -746,7 +613,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
return query.toString();
}
- private void fillAttributeQuery(
+ private void fillAttrQuery(
final StringBuilder query,
final PlainAttrValue attrValue,
final PlainSchema schema,
@@ -864,28 +731,10 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
private String getQuery(
final AttributeCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
- AnyUtils attrUtils = anyUtilsFactory.getInstance(svs.anyTypeKind);
-
- PlainSchema schema = schemaDAO.find(cond.getSchema());
- if (schema == null) {
- LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
- return EMPTY_QUERY;
- }
-
- // keep track of involvement of non-mandatory schemas in the search condition
- svs.nonMandatorySchemas = !"true".equals(schema.getMandatoryCondition());
-
- PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+ Pair<PlainSchema, PlainAttrValue> checked;
try {
- if (cond.getType() != AttributeCond.Type.LIKE
- && cond.getType() != AttributeCond.Type.ILIKE
- && cond.getType() != AttributeCond.Type.ISNULL
- && cond.getType() != AttributeCond.Type.ISNOTNULL) {
-
- schema.getValidator().validate(cond.getExpression(), attrValue);
- }
- } catch (ValidationException e) {
- LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+ checked = check(cond, svs.anyTypeKind);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
@@ -895,22 +744,22 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
query.append(svs.field().name).
append(" WHERE any_id NOT IN (SELECT any_id FROM ").
append(svs.nullAttr().name).
- append(" WHERE schema_id='").append(schema.getKey()).append("')");
+ append(" WHERE schema_id='").append(checked.getLeft().getKey()).append("')");
break;
case ISNULL:
query.append(svs.nullAttr().name).
- append(" WHERE schema_id='").append(schema.getKey()).append("'");
+ append(" WHERE schema_id='").append(checked.getLeft().getKey()).append("'");
break;
default:
- if (schema.isUniqueConstraint()) {
+ if (checked.getLeft().isUniqueConstraint()) {
query.append(svs.uniqueAttr().name);
} else {
query.append(svs.attr().name);
}
- query.append(" WHERE schema_id='").append(schema.getKey());
- fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+ query.append(" WHERE schema_id='").append(checked.getLeft().getKey());
+ fillAttrQuery(query, checked.getRight(), checked.getLeft(), cond, not, parameters, svs);
}
return query.toString();
@@ -919,78 +768,17 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO
private String getQuery(
final AnyCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
- AnyCond condClone = SerializationUtils.clone(cond);
-
- AnyUtils attrUtils = anyUtilsFactory.getInstance(svs.anyTypeKind);
-
- // Keeps track of difference between entity's getKey() and JPA @Id fields
- if ("key".equals(condClone.getSchema())) {
- condClone.setSchema("id");
- }
-
- Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), condClone.getSchema());
- if (anyField == null) {
- LOG.warn("Ignoring invalid schema '{}'", condClone.getSchema());
+ Triple<PlainSchema, PlainAttrValue, AnyCond> checked;
+ try {
+ checked = check(cond, svs.anyTypeKind);
+ } catch (IllegalArgumentException e) {
return EMPTY_QUERY;
}
- PlainSchema schema = new JPAPlainSchema();
- schema.setKey(anyField.getName());
- for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
- if (anyField.getType().isAssignableFrom(attrSchemaType.getType())) {
- schema.setType(attrSchemaType);
- }
- }
-
- // Deal with any Integer fields logically mapping to boolean values
- boolean foundBooleanMin = false;
- boolean foundBooleanMax = false;
- if (Integer.class.equals(anyField.getType())) {
- for (Annotation annotation : anyField.getAnnotations()) {
- if (Min.class.equals(annotation.annotationType())) {
- foundBooleanMin = ((Min) annotation).value() == 0;
- } else if (Max.class.equals(annotation.annotationType())) {
- foundBooleanMax = ((Max) annotation).value() == 1;
- }
- }
- }
- if (foundBooleanMin && foundBooleanMax) {
- schema.setType(AttrSchemaType.Boolean);
- }
-
- // Deal with any fields representing relationships to other entities
- if (anyField.getType().getAnnotation(Entity.class) != null) {
- Method relMethod = null;
- try {
- relMethod = ClassUtils.getPublicMethod(anyField.getType(), "getKey", new Class<?>[0]);
- } catch (Exception e) {
- LOG.error("Could not find {}#getKey", anyField.getType(), e);
- }
-
- if (relMethod != null && String.class.isAssignableFrom(relMethod.getReturnType())) {
- condClone.setSchema(condClone.getSchema() + "_id");
- schema.setType(AttrSchemaType.String);
- }
- }
-
- PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
- if (condClone.getType() != AttributeCond.Type.LIKE
- && condClone.getType() != AttributeCond.Type.ILIKE
- && condClone.getType() != AttributeCond.Type.ISNULL
- && condClone.getType() != AttributeCond.Type.ISNOTNULL) {
-
- try {
- schema.getValidator().validate(condClone.getExpression(), attrValue);
- } catch (ValidationException e) {
- LOG.error("Could not validate expression '" + condClone.getExpression() + "'", e);
- return EMPTY_QUERY;
- }
- }
-
StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
append(svs.field().name).append(" WHERE ");
- fillAttributeQuery(query, attrValue, schema, condClone, not, parameters, svs);
+ fillAttrQuery(query, checked.getMiddle(), checked.getLeft(), checked.getRight(), not, parameters, svs);
return query.toString();
}