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/08/17 16:54:26 UTC
syncope git commit: [SYNCOPE-685] Pre: re-organize SyncPoliySpec
Repository: syncope
Updated Branches:
refs/heads/master dbeb62082 -> 8fe3c7c20
[SYNCOPE-685] Pre: re-organize SyncPoliySpec
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/8fe3c7c2
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/8fe3c7c2
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/8fe3c7c2
Branch: refs/heads/master
Commit: 8fe3c7c20105df6112a1ee7b0206cb00e9c1a054
Parents: dbeb620
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Aug 17 16:54:18 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Aug 17 16:54:18 2015 +0200
----------------------------------------------------------------------
.../console/panels/BeanReflectionModal.java | 36 --
.../console/panels/BeanReflectionPanel.java | 339 -------------------
.../common/lib/annotation/ClassList.java | 26 --
.../common/lib/annotation/SchemaList.java | 28 --
.../common/lib/types/AbstractPolicySpec.java | 2 -
.../common/lib/types/SyncPolicySpec.java | 42 +--
.../common/lib/types/SyncPolicySpecItem.java | 67 ----
.../apache/syncope/core/logic/SyncopeLogic.java | 26 +-
.../init/ImplementationClassNamesLoader.java | 7 +-
.../core/persistence/jpa/inner/PolicyTest.java | 39 ++-
.../test/resources/domains/MasterContent.xml | 8 +-
.../java/data/PolicyDataBinderImpl.java | 3 -
.../sync/PlainAttrsSyncCorrelationRule.java | 110 ++++++
.../core/provisioning/java/sync/SyncUtils.java | 126 ++-----
.../fit/core/reference/PolicyITCase.java | 11 +-
.../fit/core/reference/SyncTaskITCase.java | 12 +-
16 files changed, 193 insertions(+), 689 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java
deleted file mode 100644
index a6859e8..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionModal.java
+++ /dev/null
@@ -1,36 +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.console.panels;
-
-import java.io.Serializable;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-
-/**
- * Modal window with Resource form.
- */
-public abstract class BeanReflectionModal extends ModalContent {
-
- private static final long serialVersionUID = 1734415311027284222L;
-
- public BeanReflectionModal(final Serializable bean, final ModalWindow window, final PageReference pageRef) {
- super(window, pageRef);
- add(new BeanReflectionPanel("bean", bean));
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java
deleted file mode 100644
index 4f3f1d5..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/BeanReflectionPanel.java
+++ /dev/null
@@ -1,339 +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.console.panels;
-
-import java.beans.PropertyDescriptor;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.rest.PolicyRestClient;
-import org.apache.syncope.client.console.rest.SchemaRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.form.AbstractFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.list.AltListView;
-import org.apache.syncope.common.lib.annotation.ClassList;
-import org.apache.syncope.common.lib.annotation.SchemaList;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.model.util.ListModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.util.ReflectionUtils.FieldCallback;
-import org.springframework.util.ReflectionUtils.FieldFilter;
-
-public class BeanReflectionPanel extends Panel {
-
- private static final long serialVersionUID = -3035998190456928143L;
-
- /**
- * Logger.
- */
- private static final Logger LOG = LoggerFactory.getLogger(BeanReflectionPanel.class);
-
- @SpringBean
- private SchemaRestClient schemaRestClient;
-
- @SpringBean
- private PolicyRestClient policyRestClient;
-
- private final IModel<List<String>> userSchemas = new LoadableDetachableModel<List<String>>() {
-
- private static final long serialVersionUID = -2012833443695917883L;
-
- @Override
- protected List<String> load() {
- return schemaRestClient.getPlainSchemaNames();
- }
- };
-
- private final IModel<List<String>> groupSchemas = new LoadableDetachableModel<List<String>>() {
-
- private static final long serialVersionUID = 5275935387613157437L;
-
- @Override
- protected List<String> load() {
- return schemaRestClient.getPlainSchemaNames();
- }
- };
-
- private final IModel<List<String>> correlationRules = new LoadableDetachableModel<List<String>>() {
-
- private static final long serialVersionUID = 5275935387613157437L;
-
- @Override
- protected List<String> load() {
- return policyRestClient.getCorrelationRuleClasses();
- }
- };
-
- public BeanReflectionPanel(final String id, final Serializable bean) {
- super(id);
-
- final List<FieldWrapper> items = new ArrayList<>();
- ReflectionUtils.doWithFields(bean.getClass(),
- new FieldCallback() {
-
- @Override
- public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
- FieldWrapper fieldWrapper = new FieldWrapper();
- fieldWrapper.setName(field.getName());
- fieldWrapper.setType(field.getType());
-
- final SchemaList schemaList = field.getAnnotation(SchemaList.class);
- fieldWrapper.setSchemaList(schemaList);
-
- final ClassList classList = field.getAnnotation(ClassList.class);
- fieldWrapper.setClassList(classList);
-
- items.add(fieldWrapper);
- }
- },
- new FieldFilter() {
-
- @Override
- public boolean matches(final Field field) {
- return !Modifier.isStatic(field.getModifiers()) && !"serialVersionUID".equals(field.getName());
- }
- });
-
- final ListView<FieldWrapper> policies = new AltListView<FieldWrapper>("fields", items) {
-
- private static final long serialVersionUID = 9101744072914090143L;
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected void populateItem(final ListItem<FieldWrapper> item) {
- final FieldWrapper field = item.getModelObject();
-
- final PropertyDescriptor propDesc = BeanUtils.getPropertyDescriptor(bean.getClass(), field.getName());
-
- item.add(new Label("label", new ResourceModel(field.getName())));
-
- AbstractFieldPanel component;
- try {
- if (field.getClassList() != null) {
- component = new AjaxDropDownChoicePanel("field", field.getName(), new PropertyModel(bean,
- field.getName()));
-
- final List<String> rules = correlationRules.getObject();
-
- if (rules != null && !rules.isEmpty()) {
- ((AjaxDropDownChoicePanel) component).setChoices(correlationRules.getObject());
- }
-
- item.add(component);
-
- item.add(getActivationControl(
- component,
- propDesc.getReadMethod().invoke(bean, new Object[] {}) != null,
- null,
- null));
-
- } else if (field.getType().isEnum()) {
- component = new AjaxDropDownChoicePanel("field", field.getName(), new PropertyModel(bean,
- field.getName()));
-
- final Serializable[] values = (Serializable[]) field.getType().getEnumConstants();
-
- if (values != null && values.length > 0) {
- ((AjaxDropDownChoicePanel) component).setChoices(Arrays.asList(values));
- }
-
- item.add(component);
-
- item.add(getActivationControl(
- component,
- (Enum<?>) propDesc.getReadMethod().invoke(bean, new Object[] {}) != null,
- values[0],
- values[0]));
-
- } else if (ClassUtils.isAssignable(Boolean.class, field.getType())) {
- item.add(new AjaxCheckBoxPanel("check", field.getName(),
- new PropertyModel<Boolean>(bean, field.getName())));
-
- item.add(new Label("field", new Model(null)));
- } else if (Collection.class.isAssignableFrom(field.getType())) {
- if (field.getSchemaList() != null) {
- final List<String> values = new ArrayList<>();
- if (field.getName().charAt(0) == 'r') {
- values.addAll(groupSchemas.getObject());
-
- if (field.getSchemaList().extended()) {
- values.add("name");
- }
- } else {
- values.addAll(userSchemas.getObject());
-
- if (field.getSchemaList().extended()) {
- values.add("key");
- values.add("username");
- }
- }
-
- component = new AjaxPalettePanel("field", new PropertyModel(bean, field.getName()),
- new ListModel<>(values));
- item.add(component);
-
- Collection<?> collection = (Collection) propDesc.getReadMethod().invoke(bean);
- item.add(getActivationControl(component,
- !collection.isEmpty(), new ArrayList<String>(), new ArrayList<String>()));
- } else {
- final FieldPanel panel = new AjaxTextFieldPanel("panel", field.getName(),
- new Model<String>(null));
- panel.setRequired(true);
-
- component = new MultiFieldPanel<String>("field",
- new PropertyModel(bean, field.getName()), panel);
-
- item.add(component);
-
- final List<String> reinitializedValue = new ArrayList<String>();
-
- reinitializedValue.add("");
-
- item.add(getActivationControl(component,
- !((Collection) propDesc.getReadMethod().invoke(bean, new Object[] {})).isEmpty(),
- new ArrayList<String>(), (Serializable) reinitializedValue));
- }
- } else if (ClassUtils.isAssignable(Number.class, field.getType())) {
- component = new SpinnerFieldPanel<Number>("field", field.getName(),
- (Class<Number>) field.getType(), new PropertyModel<Number>(bean, field.getName()),
- null, null);
- item.add(component);
-
- item.add(getActivationControl(component,
- (Integer) propDesc.getReadMethod().invoke(bean, new Object[] {}) > 0, 0, 0));
- } else if (field.getType().equals(String.class)) {
- component = new AjaxTextFieldPanel("field", field.getName(),
- new PropertyModel(bean, field.getName()));
-
- item.add(component);
-
- item.add(getActivationControl(component,
- propDesc.getReadMethod().invoke(bean, new Object[] {}) != null, null, null));
- } else {
- item.add(new AjaxCheckBoxPanel("check", field.getName(), new Model()));
- item.add(new Label("field", new Model(null)));
- }
- } catch (Exception e) {
- LOG.error("Error retrieving bean fields", e);
- }
- }
- };
-
- add(policies);
- }
-
- private <T extends Serializable> AjaxCheckBoxPanel getActivationControl(final AbstractFieldPanel<T> panel,
- final Boolean checked, final T defaultModelObject, final T reinitializedValue) {
-
- final AjaxCheckBoxPanel check = new AjaxCheckBoxPanel("check", "check", new Model<Boolean>(checked));
-
- panel.setEnabled(checked);
-
- check.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
- private static final long serialVersionUID = -1107858522700306810L;
-
- @Override
- protected void onUpdate(final AjaxRequestTarget target) {
- if (check.getModelObject()) {
- panel.setEnabled(true);
- panel.setModelObject(reinitializedValue);
- } else {
- panel.setModelObject(defaultModelObject);
- panel.setEnabled(false);
- }
-
- target.add(panel);
- }
- });
-
- return check;
- }
-
- private static class FieldWrapper implements Serializable {
-
- private static final long serialVersionUID = -6770429509752964215L;
-
- private Class<?> type;
-
- private String name;
-
- private transient SchemaList schemaList;
-
- private transient ClassList classList;
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-
- public Class<?> getType() {
- return type;
- }
-
- public void setType(final Class<?> type) {
- this.type = type;
- }
-
- public SchemaList getSchemaList() {
- return schemaList;
- }
-
- public void setSchemaList(final SchemaList schemaList) {
- this.schemaList = schemaList;
- }
-
- public ClassList getClassList() {
- return classList;
- }
-
- public void setClassList(final ClassList classList) {
- this.classList = classList;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
deleted file mode 100644
index 07528ea..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
+++ /dev/null
@@ -1,26 +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.common.lib.annotation;
-
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Retention(RUNTIME)
-public @interface ClassList {
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
deleted file mode 100644
index 7469731..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
+++ /dev/null
@@ -1,28 +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.common.lib.annotation;
-
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Retention(RUNTIME)
-public @interface SchemaList {
-
- boolean extended() default false;
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
index e1e7333..33a0c62 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AbstractPolicySpec.java
@@ -28,7 +28,6 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.annotation.SchemaList;
@XmlType
public abstract class AbstractPolicySpec implements PolicySpec {
@@ -43,7 +42,6 @@ public abstract class AbstractPolicySpec implements PolicySpec {
/**
* User attribute values not permitted.
*/
- @SchemaList
protected final List<String> schemasNotPermitted = new ArrayList<>();
/**
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
index 34f95dd..5a3d309 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpec.java
@@ -18,26 +18,32 @@
*/
package org.apache.syncope.common.lib.types;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
+import java.util.HashMap;
+import java.util.Map;
import javax.xml.bind.annotation.XmlType;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@XmlType
public class SyncPolicySpec implements PolicySpec {
private static final long serialVersionUID = -3144027171719498127L;
- private final List<SyncPolicySpecItem> items = new ArrayList<>();
+ private ConflictResolutionAction conflictResolutionAction;
/**
- * Conflict resolution action.
+ * Associates anyTypeKey to either:
+ * <ol>
+ * <li>Java class name, implementing {@code SyncCorrelationRule}</li>
+ * <li>JSON array containing plain schema names - this will be used to feed
+ * {@code PlainAttrsSyncCorrelationRule}</li>
+ * </ol>
*/
- private ConflictResolutionAction conflictResolutionAction;
+ @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+ @JsonIgnore
+ private final Map<String, String> correlationRules = new HashMap<>();
public ConflictResolutionAction getConflictResolutionAction() {
return conflictResolutionAction == null
@@ -49,20 +55,8 @@ public class SyncPolicySpec implements PolicySpec {
this.conflictResolutionAction = conflictResolutionAction;
}
- public SyncPolicySpecItem getItem(final String anyTypeKey) {
- return CollectionUtils.find(items, new Predicate<SyncPolicySpecItem>() {
-
- @Override
- public boolean evaluate(final SyncPolicySpecItem item) {
- return anyTypeKey != null && anyTypeKey.equals(item.getAnyTypeKey());
- }
- });
- }
-
- @XmlElementWrapper(name = "items")
- @XmlElement(name = "item")
- @JsonProperty("items")
- public List<SyncPolicySpecItem> getItems() {
- return items;
+ @JsonProperty
+ public Map<String, String> getCorrelationRules() {
+ return correlationRules;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
deleted file mode 100644
index 4acb61b..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SyncPolicySpecItem.java
+++ /dev/null
@@ -1,67 +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.common.lib.types;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.annotation.ClassList;
-import org.apache.syncope.common.lib.annotation.SchemaList;
-
-@XmlType
-public class SyncPolicySpecItem extends AbstractBaseBean {
-
- private static final long serialVersionUID = 692466729711976485L;
-
- private String anyTypeKey;
-
- @SchemaList(extended = true)
- private final List<String> altSearchSchemas = new ArrayList<>();
-
- @ClassList
- private String javaRule;
-
- public String getAnyTypeKey() {
- return anyTypeKey;
- }
-
- public void setAnyTypeKey(final String anyTypeKey) {
- this.anyTypeKey = anyTypeKey;
- }
-
- public String getJavaRule() {
- return javaRule;
- }
-
- public void setJavaRule(final String javaRule) {
- this.javaRule = javaRule;
- }
-
- @XmlElementWrapper(name = "altSearchSchemas")
- @XmlElement(name = "altSearchSchema")
- @JsonProperty("altSearchSchemas")
- public List<String> getAltSearchSchemas() {
- return altSearchSchemas;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/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 8dd20a8..d6432e2 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
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.core.logic;
+import static org.apache.syncope.core.logic.init.ImplementationClassNamesLoader.Type;
+
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
@@ -128,22 +130,14 @@ public class SyncopeLogic extends AbstractLogic<SyncopeTO> {
syncopeTO.setGroupProvisioningManager(gProvisioningManager.getClass().getName());
syncopeTO.setVirAttrCache(virAttrCache.getClass().getName());
- syncopeTO.getReportlets().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET));
- syncopeTO.getTaskJobs().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.TASKJOBDELEGATE));
- syncopeTO.getPropagationActions().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PROPAGATION_ACTIONS));
- syncopeTO.getSyncActions().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_ACTIONS));
- syncopeTO.getPushActions().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_ACTIONS));
- syncopeTO.getSyncCorrelationRules().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.SYNC_CORRELATION_RULE));
- syncopeTO.getPushCorrelationRules().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.PUSH_CORRELATION_RULE));
- syncopeTO.getValidators().addAll(
- classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.VALIDATOR));
+ syncopeTO.getReportlets().addAll(classNamesLoader.getClassNames(Type.REPORTLET));
+ syncopeTO.getTaskJobs().addAll(classNamesLoader.getClassNames(Type.TASKJOBDELEGATE));
+ syncopeTO.getPropagationActions().addAll(classNamesLoader.getClassNames(Type.PROPAGATION_ACTIONS));
+ syncopeTO.getSyncActions().addAll(classNamesLoader.getClassNames(Type.SYNC_ACTIONS));
+ syncopeTO.getPushActions().addAll(classNamesLoader.getClassNames(Type.PUSH_ACTIONS));
+ syncopeTO.getSyncCorrelationRules().addAll(classNamesLoader.getClassNames(Type.SYNC_CORRELATION_RULE));
+ syncopeTO.getPushCorrelationRules().addAll(classNamesLoader.getClassNames(Type.PUSH_CORRELATION_RULE));
+ syncopeTO.getValidators().addAll(classNamesLoader.getClassNames(Type.VALIDATOR));
Set<String> htmlTemplates = new HashSet<>();
Set<String> textTemplates = new HashSet<>();
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
index 2bcd78f..1b53e5c 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
@@ -62,9 +62,6 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
}
- /**
- * Logger.
- */
private static final Logger LOG = LoggerFactory.getLogger(ImplementationClassNamesLoader.class);
private Map<Type, Set<String>> classNames;
@@ -87,7 +84,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(SyncCorrelationRule.class));
- // Remove once SYNCOPE-631 is done
+ // Remove once SYNCOPE-470 is done
//scanner.addIncludeFilter(new AssignableTypeFilter(PushCorrelationRule.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PropagationActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(Validator.class));
@@ -121,7 +118,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
classNames.get(Type.SYNC_CORRELATION_RULE).add(bd.getBeanClassName());
}
- // Uncomment when SYNCOPE-631 is done
+ // Uncomment when SYNCOPE-470 is done
/* if (PushCorrelationRule.class.isAssignableFrom(clazz) && !isAbsractClazz) {
* classNames.get(Type.PUSH_CORRELATION_RULES).add(metadata.getClassName());
* } */
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
index c75a148..603cd01 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -22,12 +22,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.PasswordPolicySpec;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.SyncPolicySpec;
-import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
@@ -55,9 +58,20 @@ public class PolicyTest extends AbstractTest {
}
@Test
- public void findById() {
- Policy policy = policyDAO.find(1L);
+ public void findByKey() {
+ SyncPolicy policy = policyDAO.find(3L);
assertNotNull("findById did not work", policy);
+
+ SyncPolicySpec spec = policy.getSpecification(SyncPolicySpec.class);
+ assertNotNull(spec);
+
+ String rule = spec.getCorrelationRules().get(AnyTypeKind.USER.name());
+ assertNotNull(rule);
+ String[] plainSchemas = POJOHelper.deserialize(rule, String[].class);
+ assertNotNull(plainSchemas);
+ assertEquals(2, plainSchemas.length);
+ assertTrue(ArrayUtils.contains(plainSchemas, "username"));
+ assertTrue(ArrayUtils.contains(plainSchemas, "firstname"));
}
@Test
@@ -89,15 +103,8 @@ public class PolicyTest extends AbstractTest {
SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
- SyncPolicySpecItem item = new SyncPolicySpecItem();
- item.setAnyTypeKey(anyTypeDAO.findUser().getKey());
- item.setJavaRule(syncURuleName);
- syncPolicySpec.getItems().add(item);
-
- item = new SyncPolicySpecItem();
- item.setAnyTypeKey(anyTypeDAO.findGroup().getKey());
- item.setJavaRule(syncGRuleName);
- syncPolicySpec.getItems().add(item);
+ syncPolicySpec.getCorrelationRules().put(anyTypeDAO.findUser().getKey(), syncURuleName);
+ syncPolicySpec.getCorrelationRules().put(anyTypeDAO.findGroup().getKey(), syncGRuleName);
policy.setSpecification(syncPolicySpec);
policy.setDescription("Sync policy");
@@ -106,10 +113,10 @@ public class PolicyTest extends AbstractTest {
assertNotNull(policy);
assertEquals(PolicyType.SYNC, policy.getType());
- assertEquals(syncURuleName,
- (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findUser().getKey()).getJavaRule());
- assertEquals(syncGRuleName,
- (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findGroup().getKey()).getJavaRule());
+ assertEquals(syncURuleName, (policy.getSpecification(SyncPolicySpec.class)).
+ getCorrelationRules().get(anyTypeDAO.findUser().getKey()));
+ assertEquals(syncGRuleName, (policy.getSpecification(SyncPolicySpec.class)).
+ getCorrelationRules().get(anyTypeDAO.findGroup().getKey()));
}
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/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 37ff60f..5977c9a 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -101,11 +101,11 @@ under the License.
<!-- sample policies -->
<Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC"
- specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+ specification='{"conflictResolutionAction":"IGNORE"'/>
<Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD"
specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
<Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC"
- specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
+ specification='{"conflictResolutionAction":"ALL","correlationRules":{"USER":"[\"username\",\"firstname\"]"}}'/>
<Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD"
specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[], "allowNullPassword":true}'/>
<Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT"
@@ -113,11 +113,11 @@ under the License.
<Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT"
specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
<Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC"
- specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+ specification='{"conflictResolutionAction":"IGNORE"}'/>
<Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD"
specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":true,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":true,"uppercaseRequired":true,"mustStartWithDigit":true,"mustntStartWithDigit":false,"mustEndWithDigit":true,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":false}'/>
<Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC"
- specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
+ specification='{"conflictResolutionAction":"IGNORE"}'/>
<RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
<RelationshipType name="neighborhood"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index fde025d..fa53bbd 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -45,9 +45,6 @@ import org.springframework.stereotype.Component;
@Component
public class PolicyDataBinderImpl implements PolicyDataBinder {
- /**
- * Logger.
- */
private static final Logger LOG = LoggerFactory.getLogger(PolicyDataBinder.class);
@Autowired
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
new file mode 100644
index 0000000..1af195e
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/PlainAttrsSyncCorrelationRule.java
@@ -0,0 +1,110 @@
+/*
+ * 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.provisioning.java.sync;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+public class PlainAttrsSyncCorrelationRule implements SyncCorrelationRule {
+
+ private final List<String> plainSchemaNames;
+
+ private final Provision provision;
+
+ public PlainAttrsSyncCorrelationRule(final String[] plainSchemaNames, final Provision provision) {
+ this.plainSchemaNames = Arrays.asList(plainSchemaNames);
+ this.provision = provision;
+ }
+
+ @Override
+ public SearchCond getSearchCond(final ConnectorObject connObj) {
+ // search for external attribute's name/value of each specified name
+ Map<String, Attribute> extValues = new HashMap<>();
+
+ for (MappingItem item : MappingUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
+ extValues.put(item.getIntAttrName(), connObj.getAttributeByName(item.getExtAttrName()));
+ }
+
+ // search for user/group by attribute(s) specified in the policy
+ SearchCond searchCond = null;
+
+ for (String schema : plainSchemaNames) {
+ Attribute value = extValues.get(schema);
+
+ if (value == null) {
+ throw new IllegalArgumentException(
+ "Connector object does not contains the attributes to perform the search: " + schema);
+ }
+
+ AttributeCond.Type type;
+ String expression = null;
+
+ if (value.getValue() == null || value.getValue().isEmpty()
+ || (value.getValue().size() == 1 && value.getValue().get(0) == null)) {
+
+ type = AttributeCond.Type.ISNULL;
+ } else {
+ type = AttributeCond.Type.EQ;
+ expression = value.getValue().size() > 1
+ ? value.getValue().toString()
+ : value.getValue().get(0).toString();
+ }
+
+ SearchCond nodeCond;
+ // users: just id or username can be selected to be used
+ // groups: just id or name can be selected to be used
+ if ("key".equalsIgnoreCase(schema)
+ || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
+
+ AnyCond cond = new AnyCond();
+ cond.setSchema(schema);
+ cond.setType(type);
+ cond.setExpression(expression);
+
+ nodeCond = SearchCond.getLeafCond(cond);
+ } else {
+ AttributeCond cond = new AttributeCond();
+ cond.setSchema(schema);
+ cond.setType(type);
+ cond.setExpression(expression);
+
+ nodeCond = SearchCond.getLeafCond(cond);
+ }
+
+ searchCond = searchCond == null
+ ? nodeCond
+ : SearchCond.getAndCond(searchCond, nodeCond);
+ }
+
+ return searchCond;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
index dc5cdf0..7fd244b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/SyncUtils.java
@@ -20,15 +20,14 @@ package org.apache.syncope.core.provisioning.java.sync;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.MappingPurpose;
import org.apache.syncope.common.lib.types.SyncPolicySpec;
import org.apache.syncope.core.misc.MappingUtils;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -36,10 +35,7 @@ import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
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.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-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.AnyType;
import org.apache.syncope.core.persistence.api.entity.AnyUtils;
@@ -230,11 +226,15 @@ public class SyncUtils {
return result;
}
- private List<Long> search(final SearchCond searchCond, final AnyTypeKind type) {
- final List<Long> result = new ArrayList<>();
+ private List<Long> findByCorrelationRule(
+ final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
+
+ List<Long> result = new ArrayList<>();
List<Any<?, ?, ?>> anys = searchDAO.search(
- SyncopeConstants.FULL_ADMIN_REALMS, searchCond, Collections.<OrderByClause>emptyList(), type);
+ SyncopeConstants.FULL_ADMIN_REALMS,
+ rule.getSearchCond(connObj),
+ Collections.<OrderByClause>emptyList(), type);
for (Any<?, ?, ?> any : anys) {
result.add(any.getKey());
}
@@ -242,101 +242,24 @@ public class SyncUtils {
return result;
}
- private List<Long> findByCorrelationRule(
- final ConnectorObject connObj, final SyncCorrelationRule rule, final AnyTypeKind type) {
-
- return search(rule.getSearchCond(connObj), type);
- }
-
- private List<Long> findByAnySearch(
- final ConnectorObject connObj,
- final List<String> altSearchSchemas,
- final Provision provision,
- final AnyTypeKind anyTypeKind) {
-
- // search for external attribute's name/value of each specified name
- Map<String, Attribute> extValues = new HashMap<>();
-
- for (MappingItem item : MappingUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
- extValues.put(item.getIntAttrName(), connObj.getAttributeByName(item.getExtAttrName()));
- }
-
- // search for user/group by attribute(s) specified in the policy
- SearchCond searchCond = null;
-
- for (String schema : altSearchSchemas) {
- Attribute value = extValues.get(schema);
-
- if (value == null) {
- throw new IllegalArgumentException(
- "Connector object does not contains the attributes to perform the search: " + schema);
- }
-
- AttributeCond.Type type;
- String expression = null;
-
- if (value.getValue() == null || value.getValue().isEmpty()
- || (value.getValue().size() == 1 && value.getValue().get(0) == null)) {
-
- type = AttributeCond.Type.ISNULL;
- } else {
- type = AttributeCond.Type.EQ;
- expression = value.getValue().size() > 1
- ? value.getValue().toString()
- : value.getValue().get(0).toString();
- }
-
- SearchCond nodeCond;
- // users: just id or username can be selected to be used
- // groups: just id or name can be selected to be used
- if ("key".equalsIgnoreCase(schema)
- || "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
-
- AnyCond cond = new AnyCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- } else {
- AttributeCond cond = new AttributeCond();
- cond.setSchema(schema);
- cond.setType(type);
- cond.setExpression(expression);
-
- nodeCond = SearchCond.getLeafCond(cond);
- }
-
- searchCond = searchCond == null
- ? nodeCond
- : SearchCond.getAndCond(searchCond, nodeCond);
- }
-
- return search(searchCond, anyTypeKind);
- }
-
private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
- String clazz = policySpec.getItem(provision.getAnyType().getKey()) == null
- ? null
- : policySpec.getItem(provision.getAnyType().getKey()).getJavaRule();
-
- SyncCorrelationRule res = null;
+ SyncCorrelationRule result = null;
- if (StringUtils.isNotBlank(clazz)) {
- try {
- res = (SyncCorrelationRule) Class.forName(clazz).newInstance();
- } catch (Exception e) {
- LOG.error("Failure instantiating correlation rule class '{}'", clazz, e);
+ String syncCorrelationRule = policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
+ if (StringUtils.isNotBlank(syncCorrelationRule)) {
+ if (syncCorrelationRule.charAt(0) == '[') {
+ result = new PlainAttrsSyncCorrelationRule(
+ POJOHelper.deserialize(syncCorrelationRule, String[].class), provision);
+ } else {
+ try {
+ result = (SyncCorrelationRule) Class.forName(syncCorrelationRule).newInstance();
+ } catch (Exception e) {
+ LOG.error("Failure instantiating correlation rule class '{}'", syncCorrelationRule, e);
+ }
}
}
- return res;
- }
-
- private List<String> getAltSearchSchemas(final Provision provision, final SyncPolicySpec policySpec) {
- return policySpec.getItem(provision.getAnyType().getKey()) == null
- ? Collections.<String>emptyList()
- : policySpec.getItem(provision.getAnyType().getKey()).getAltSearchSchemas();
+ return result;
}
/**
@@ -360,17 +283,12 @@ public class SyncUtils {
}
SyncCorrelationRule syncRule = null;
- List<String> altSearchSchemas = null;
-
if (syncPolicySpec != null) {
syncRule = getCorrelationRule(provision, syncPolicySpec);
- altSearchSchemas = getAltSearchSchemas(provision, syncPolicySpec);
}
return syncRule == null
- ? altSearchSchemas == null || altSearchSchemas.isEmpty()
- ? findByConnObjectKeyItem(uid, provision, anyUtils)
- : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils.getAnyTypeKind())
+ ? findByConnObjectKeyItem(uid, provision, anyUtils)
: findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
index 0098821..95701ae 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PolicyITCase.java
@@ -36,7 +36,6 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PasswordPolicySpec;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.SyncPolicySpec;
-import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@@ -47,12 +46,8 @@ public class PolicyITCase extends AbstractITCase {
private SyncPolicyTO buildSyncPolicyTO() {
SyncPolicyTO policy = new SyncPolicyTO();
- SyncPolicySpecItem item = new SyncPolicySpecItem();
- item.setAnyTypeKey(AnyTypeKind.USER.name());
- item.setJavaRule(TestSyncRule.class.getName());
-
SyncPolicySpec spec = new SyncPolicySpec();
- spec.getItems().add(item);
+ spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
policy.setSpecification(spec);
policy.setDescription("Sync policy");
@@ -116,7 +111,7 @@ public class PolicyITCase extends AbstractITCase {
assertNotNull(policyTO);
assertEquals(PolicyType.SYNC, policyTO.getType());
assertEquals(TestSyncRule.class.getName(),
- policyTO.getSpecification().getItem(AnyTypeKind.USER.name()).getJavaRule());
+ policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name()));
}
@Test
@@ -169,7 +164,7 @@ public class PolicyITCase extends AbstractITCase {
@Test
public void getCorrelationRules() {
- assertEquals(1, syncopeService.info().getSyncCorrelationRules().size());
+ assertEquals(2, syncopeService.info().getSyncCorrelationRules().size());
}
@Test
http://git-wip-us.apache.org/repos/asf/syncope/blob/8fe3c7c2/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 4313c00..d97eaed 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
@@ -55,7 +55,6 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.ConnConfProperty;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
-import org.apache.syncope.common.lib.types.SyncPolicySpecItem;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.wrap.ResourceKey;
import org.apache.syncope.common.rest.api.CollectionWrapper;
@@ -505,16 +504,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
// Add a custom correlation rule
// -----------------------------
SyncPolicyTO policyTO = policyService.read(9L);
-
- SyncPolicySpecItem item = policyTO.getSpecification().getItem(AnyTypeKind.USER.name());
- if (item == null) {
- item = new SyncPolicySpecItem();
- item.setAnyTypeKey(AnyTypeKind.USER.name());
-
- policyTO.getSpecification().getItems().add(item);
- }
- item.setJavaRule(TestSyncRule.class.getName());
-
+ policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestSyncRule.class.getName());
policyService.update(policyTO);
// -----------------------------