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/01/08 14:17:27 UTC
[07/13] syncope git commit: [SYNCOPE-620] server logic in,
tests missing
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConfigurationDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConfigurationDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConfigurationDataBinder.java
new file mode 100644
index 0000000..64c4a4e
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConfigurationDataBinder.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.logic.data;
+
+import java.util.Collections;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConfTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.persistence.api.dao.NotFoundException;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+import org.apache.syncope.persistence.api.entity.conf.CPlainAttr;
+import org.apache.syncope.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.persistence.api.entity.conf.Conf;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ConfigurationDataBinder extends AbstractAttributableDataBinder {
+
+ public ConfTO getConfTO(final Conf conf) {
+ final ConfTO confTO = new ConfTO();
+ confTO.setKey(conf.getKey());
+
+ fillTO(confTO, conf.getPlainAttrs(),
+ conf.getDerAttrs(), conf.getVirAttrs(), Collections.<ExternalResource>emptySet());
+
+ return confTO;
+ }
+
+ public AttrTO getAttrTO(final CPlainAttr attr) {
+ final AttrTO attributeTO = new AttrTO();
+ attributeTO.setSchema(attr.getSchema().getKey());
+ attributeTO.getValues().addAll(attr.getValuesAsStrings());
+ attributeTO.setReadonly(attr.getSchema().isReadonly());
+
+ return attributeTO;
+ }
+
+ public CPlainAttr getAttribute(final AttrTO attributeTO) {
+ CPlainSchema schema = getPlainSchema(attributeTO.getSchema(), CPlainSchema.class);
+ if (schema == null) {
+ throw new NotFoundException("Conf schema " + attributeTO.getSchema());
+ } else {
+ SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
+
+ CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class);
+ attr.setSchema(schema);
+ fillAttribute(attributeTO.getValues(), attrUtilFactory.getInstance(AttributableType.CONFIGURATION),
+ schema, attr, invalidValues);
+
+ if (!invalidValues.isEmpty()) {
+ throw invalidValues;
+ }
+ return attr;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConnInstanceDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConnInstanceDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConnInstanceDataBinder.java
new file mode 100644
index 0000000..1091be1
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ConnInstanceDataBinder.java
@@ -0,0 +1,246 @@
+/*
+ * 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.server.logic.data;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.persistence.api.entity.ConnInstance;
+import org.apache.syncope.persistence.api.entity.EntityFactory;
+import org.apache.syncope.provisioning.api.ConnIdBundleManager;
+import org.apache.syncope.provisioning.api.ConnPoolConfUtil;
+import org.identityconnectors.framework.api.ConfigurationProperties;
+import org.identityconnectors.framework.api.ConfigurationProperty;
+import org.identityconnectors.framework.impl.api.ConfigurationPropertyImpl;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ConnInstanceDataBinder {
+
+ private static final String[] IGNORE_PROPERTIES = { "key", "poolConf" };
+
+ @Autowired
+ private ConnIdBundleManager connIdBundleManager;
+
+ @Autowired
+ private ConnInstanceDAO connInstanceDAO;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ /**
+ * Merge connector configuration properties avoiding repetition but giving priority to primary set.
+ *
+ * @param primary primary set.
+ * @param secondary secondary set.
+ * @return merged set.
+ */
+ public Set<ConnConfProperty> mergeConnConfProperties(final Set<ConnConfProperty> primary,
+ final Set<ConnConfProperty> secondary) {
+
+ final Set<ConnConfProperty> conf = new HashSet<>();
+
+ // to be used to control managed prop (needed by overridden mechanism)
+ final Set<String> propertyNames = new HashSet<>();
+
+ // get overridden connector configuration properties
+ for (ConnConfProperty prop : primary) {
+ if (!propertyNames.contains(prop.getSchema().getName())) {
+ conf.add(prop);
+ propertyNames.add(prop.getSchema().getName());
+ }
+ }
+
+ // get connector configuration properties
+ for (ConnConfProperty prop : secondary) {
+ if (!propertyNames.contains(prop.getSchema().getName())) {
+ conf.add(prop);
+ propertyNames.add(prop.getSchema().getName());
+ }
+ }
+
+ return conf;
+ }
+
+ public ConnInstance getConnInstance(final ConnInstanceTO connInstanceTO) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
+
+ if (connInstanceTO.getLocation() == null) {
+ sce.getElements().add("location");
+ }
+
+ if (connInstanceTO.getBundleName() == null) {
+ sce.getElements().add("bundlename");
+ }
+
+ if (connInstanceTO.getVersion() == null) {
+ sce.getElements().add("bundleversion");
+ }
+
+ if (connInstanceTO.getConnectorName() == null) {
+ sce.getElements().add("connectorname");
+ }
+
+ if (connInstanceTO.getConfiguration() == null || connInstanceTO.getConfiguration().isEmpty()) {
+ sce.getElements().add("configuration");
+ }
+
+ ConnInstance connInstance = entityFactory.newEntity(ConnInstance.class);
+
+ BeanUtils.copyProperties(connInstanceTO, connInstance, IGNORE_PROPERTIES);
+ if (connInstanceTO.getLocation() != null) {
+ connInstance.setLocation(connInstanceTO.getLocation());
+ }
+ if (connInstanceTO.getPoolConf() != null) {
+ connInstance.setPoolConf(
+ ConnPoolConfUtil.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
+ }
+
+ // Throw exception if there is at least one element set
+ if (!sce.isEmpty()) {
+ throw sce;
+ }
+
+ return connInstance;
+ }
+
+ public ConnInstance updateConnInstance(final long connInstanceId, final ConnInstanceTO connInstanceTO) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
+
+ if (connInstanceId == 0) {
+ sce.getElements().add("connector id");
+ }
+
+ ConnInstance connInstance = connInstanceDAO.find(connInstanceId);
+ connInstance.getCapabilities().clear();
+ connInstance.getCapabilities().addAll(connInstanceTO.getCapabilities());
+
+ if (connInstanceTO.getLocation() != null) {
+ connInstance.setLocation(connInstanceTO.getLocation());
+ }
+
+ if (connInstanceTO.getBundleName() != null) {
+ connInstance.setBundleName(connInstanceTO.getBundleName());
+ }
+
+ if (connInstanceTO.getVersion() != null) {
+ connInstance.setVersion(connInstanceTO.getVersion());
+ }
+
+ if (connInstanceTO.getConnectorName() != null) {
+ connInstance.setConnectorName(connInstanceTO.getConnectorName());
+ }
+
+ if (connInstanceTO.getConfiguration() != null && !connInstanceTO.getConfiguration().isEmpty()) {
+ connInstance.setConfiguration(connInstanceTO.getConfiguration());
+ }
+
+ if (connInstanceTO.getDisplayName() != null) {
+ connInstance.setDisplayName(connInstanceTO.getDisplayName());
+ }
+
+ if (connInstanceTO.getConnRequestTimeout() != null) {
+ connInstance.setConnRequestTimeout(connInstanceTO.getConnRequestTimeout());
+ }
+
+ if (connInstanceTO.getPoolConf() == null) {
+ connInstance.setPoolConf(null);
+ } else {
+ connInstance.setPoolConf(
+ ConnPoolConfUtil.getConnPoolConf(connInstanceTO.getPoolConf(), entityFactory.newConnPoolConf()));
+ }
+
+ if (!sce.isEmpty()) {
+ throw sce;
+ }
+
+ return connInstance;
+ }
+
+ public ConnConfPropSchema buildConnConfPropSchema(final ConfigurationProperty property) {
+ ConnConfPropSchema connConfPropSchema = new ConnConfPropSchema();
+
+ connConfPropSchema.setName(property.getName());
+ connConfPropSchema.setDisplayName(property.getDisplayName(property.getName()));
+ connConfPropSchema.setHelpMessage(property.getHelpMessage(property.getName()));
+ connConfPropSchema.setRequired(property.isRequired());
+ connConfPropSchema.setType(property.getType().getName());
+ connConfPropSchema.setOrder(((ConfigurationPropertyImpl) property).getOrder());
+ connConfPropSchema.setConfidential(property.isConfidential());
+
+ if (property.getValue() != null) {
+ if (property.getValue().getClass().isArray()) {
+ connConfPropSchema.getDefaultValues().addAll(Arrays.asList((Object[]) property.getValue()));
+ } else if (property.getValue() instanceof Collection<?>) {
+ connConfPropSchema.getDefaultValues().addAll((Collection<?>) property.getValue());
+ } else {
+ connConfPropSchema.getDefaultValues().add(property.getValue());
+ }
+ }
+
+ return connConfPropSchema;
+ }
+
+ public ConnInstanceTO getConnInstanceTO(final ConnInstance connInstance) {
+ ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+ connInstanceTO.setKey(connInstance.getKey() == null ? 0L : connInstance.getKey());
+
+ // retrieve the ConfigurationProperties
+ ConfigurationProperties properties = connIdBundleManager.getConfigurationProperties(
+ connIdBundleManager.getConnectorInfo(connInstance.getLocation(),
+ connInstance.getBundleName(), connInstance.getVersion(), connInstance.getConnectorName()));
+
+ BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
+
+ final Map<String, ConnConfProperty> connInstanceToConfMap = connInstanceTO.getConfigurationMap();
+
+ for (String propName : properties.getPropertyNames()) {
+ ConnConfPropSchema schema = buildConnConfPropSchema(properties.getProperty(propName));
+
+ ConnConfProperty property;
+ if (connInstanceToConfMap.containsKey(propName)) {
+ property = connInstanceToConfMap.get(propName);
+ } else {
+ property = new ConnConfProperty();
+ connInstanceTO.getConfiguration().add(property);
+ }
+
+ property.setSchema(schema);
+ }
+
+ if (connInstance.getPoolConf() != null) {
+ ConnPoolConfTO poolConf = new ConnPoolConfTO();
+ BeanUtils.copyProperties(connInstance.getPoolConf(), poolConf);
+ connInstanceTO.setPoolConf(poolConf);
+ }
+
+ return connInstanceTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/NotificationDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/NotificationDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/NotificationDataBinder.java
new file mode 100644
index 0000000..0ddb74e
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/NotificationDataBinder.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server.logic.data;
+
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.persistence.api.entity.EntityFactory;
+import org.apache.syncope.persistence.api.entity.Notification;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class NotificationDataBinder {
+
+ private static final String[] IGNORE_PROPERTIES = { "key", "about", "recipients" };
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ public NotificationTO getNotificationTO(final Notification notification) {
+ NotificationTO result = new NotificationTO();
+
+ BeanUtils.copyProperties(notification, result, IGNORE_PROPERTIES);
+
+ result.setKey(notification.getKey());
+ result.setUserAbout(notification.getUserAbout());
+ result.setRoleAbout(notification.getRoleAbout());
+ result.setRecipients(notification.getRecipients());
+
+ return result;
+ }
+
+ public Notification create(final NotificationTO notificationTO) {
+ Notification result = entityFactory.newEntity(Notification.class);
+ update(result, notificationTO);
+ return result;
+ }
+
+ public void update(final Notification notification, final NotificationTO notificationTO) {
+ BeanUtils.copyProperties(notificationTO, notification, IGNORE_PROPERTIES);
+
+ notification.setUserAbout(notificationTO.getUserAbout());
+ notification.setRoleAbout(notificationTO.getRoleAbout());
+ notification.setRecipients(notificationTO.getRecipients());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/PolicyDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/PolicyDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/PolicyDataBinder.java
new file mode 100644
index 0000000..57877d2
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/PolicyDataBinder.java
@@ -0,0 +1,186 @@
+/*
+ * 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.server.logic.data;
+
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.persistence.api.dao.RoleDAO;
+import org.apache.syncope.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.persistence.api.entity.EntityFactory;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+import org.apache.syncope.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.persistence.api.entity.Policy;
+import org.apache.syncope.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.persistence.api.entity.role.Role;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PolicyDataBinder {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(PolicyDataBinder.class);
+
+ @Autowired
+ private ExternalResourceDAO resourceDAO;
+
+ @Autowired
+ private RoleDAO roleDAO;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ /**
+ * Get policy TO from policy bean.
+ *
+ * @param policy bean.
+ * @return policy TO.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends AbstractPolicyTO> T getPolicyTO(final Policy policy) {
+ final T policyTO;
+
+ switch (policy.getType()) {
+ case GLOBAL_PASSWORD:
+ case PASSWORD:
+ policyTO = (T) new PasswordPolicyTO(policy.getType().isGlobal());
+ ((PasswordPolicyTO) policyTO).setSpecification(policy.getSpecification(PasswordPolicySpec.class));
+ break;
+
+ case GLOBAL_ACCOUNT:
+ case ACCOUNT:
+ policyTO = (T) new AccountPolicyTO(policy.getType().isGlobal());
+ ((AccountPolicyTO) policyTO).setSpecification(policy.getSpecification(AccountPolicySpec.class));
+ ((AccountPolicyTO) policyTO).getResources().addAll(((AccountPolicy) policy).getResourceNames());
+ break;
+
+ case GLOBAL_SYNC:
+ case SYNC:
+ default:
+ policyTO = (T) new SyncPolicyTO(policy.getType().isGlobal());
+ ((SyncPolicyTO) policyTO).setSpecification(policy.getSpecification(SyncPolicySpec.class));
+ }
+
+ policyTO.setId(policy.getKey());
+ policyTO.setDescription(policy.getDescription());
+
+ for (ExternalResource resource : resourceDAO.findByPolicy(policy)) {
+ policyTO.getUsedByResources().add(resource.getKey());
+ }
+ if (policy.getType().isGlobal()) {
+ for (ExternalResource resource : resourceDAO.findWithoutPolicy(policy.getType())) {
+ policyTO.getUsedByResources().add(resource.getKey());
+ }
+ }
+ for (Role role : roleDAO.findByPolicy(policy)) {
+ policyTO.getUsedByRoles().add(role.getKey());
+ }
+ if (policy.getType().isGlobal()) {
+ for (Role role : roleDAO.findWithoutPolicy(policy.getType())) {
+ policyTO.getUsedByRoles().add(role.getKey());
+ }
+ }
+
+ return policyTO;
+ }
+
+ private ExternalResource getResource(final String resourceName) {
+ ExternalResource resource = resourceDAO.find(resourceName);
+ if (resource == null) {
+ LOG.debug("Ignoring invalid resource {} ", resourceName);
+ }
+
+ return resource;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Policy> T getPolicy(T policy, final AbstractPolicyTO policyTO) {
+ if (policy != null && policy.getType() != policyTO.getType()) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
+ sce.getElements().add(String.format("Cannot update %s from %s", policy.getType(), policyTO.getType()));
+ throw sce;
+ }
+
+ switch (policyTO.getType()) {
+ case GLOBAL_PASSWORD:
+ case PASSWORD:
+ if (!(policyTO instanceof PasswordPolicyTO)) {
+ throw new ClassCastException("Expected " + PasswordPolicyTO.class.getName()
+ + ", found " + policyTO.getClass().getName());
+ }
+ if (policy == null) {
+ policy = (T) entityFactory.newPolicy(PasswordPolicy.class, policyTO.getType().isGlobal());
+ }
+ policy.setSpecification(((PasswordPolicyTO) policyTO).getSpecification());
+ break;
+
+ case GLOBAL_ACCOUNT:
+ case ACCOUNT:
+ if (!(policyTO instanceof AccountPolicyTO)) {
+ throw new ClassCastException("Expected " + AccountPolicyTO.class.getName()
+ + ", found " + policyTO.getClass().getName());
+ }
+ if (policy == null) {
+ policy = (T) entityFactory.newPolicy(AccountPolicy.class, policyTO.getType().isGlobal());
+ }
+ policy.setSpecification(((AccountPolicyTO) policyTO).getSpecification());
+
+ if (((AccountPolicy) policy).getResources() != null
+ && !((AccountPolicy) policy).getResources().isEmpty()) {
+ ((AccountPolicy) policy).getResources().clear();
+ }
+ for (String resourceName : ((AccountPolicyTO) policyTO).getResources()) {
+ ExternalResource resource = getResource(resourceName);
+
+ if (resource != null) {
+ ((AccountPolicy) policy).addResource(resource);
+ }
+ }
+ break;
+
+ case GLOBAL_SYNC:
+ case SYNC:
+ default:
+ if (!(policyTO instanceof SyncPolicyTO)) {
+ throw new ClassCastException("Expected " + SyncPolicyTO.class.getName()
+ + ", found " + policyTO.getClass().getName());
+ }
+ if (policy == null) {
+ policy = (T) entityFactory.newPolicy(SyncPolicy.class, policyTO.getType().isGlobal());
+ }
+ policy.setSpecification(((SyncPolicyTO) policyTO).getSpecification());
+ }
+
+ policy.setDescription(policyTO.getDescription());
+
+ return policy;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ReportDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ReportDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ReportDataBinder.java
new file mode 100644
index 0000000..952de94
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ReportDataBinder.java
@@ -0,0 +1,175 @@
+/*
+ * 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.server.logic.data;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.common.lib.report.AbstractReportletConf;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.persistence.api.entity.Report;
+import org.apache.syncope.persistence.api.entity.ReportExec;
+import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
+import org.apache.syncope.server.logic.report.Reportlet;
+import org.apache.syncope.server.logic.init.JobInstanceLoader;
+import org.apache.syncope.server.logic.report.ReportletConfClass;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.TriggerKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+
+@Component
+public class ReportDataBinder {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ReportDataBinder.class);
+
+ private static final String[] IGNORE_REPORT_PROPERTIES = { "key", "reportlets", "executions" };
+
+ private static final String[] IGNORE_REPORT_EXECUTION_PROPERTIES = { "key", "report", "execResult" };
+
+ @Autowired
+ private ReportExecDAO reportExecDAO;
+
+ @Autowired
+ private SchedulerFactoryBean scheduler;
+
+ @Autowired
+ private ImplementationClassNamesLoader classNamesLoader;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Set<Class<Reportlet>> getAllReportletClasses() {
+ Set<Class<Reportlet>> reportletClasses = new HashSet<Class<Reportlet>>();
+
+ for (String className : classNamesLoader.getClassNames(ImplementationClassNamesLoader.Type.REPORTLET)) {
+ try {
+ Class reportletClass = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
+ reportletClasses.add(reportletClass);
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not load class {}", className);
+ } catch (LinkageError e) {
+ LOG.warn("Could not link class {}", className);
+ }
+ }
+ return reportletClasses;
+ }
+
+ public Class<? extends ReportletConf> getReportletConfClass(final Class<Reportlet> reportletClass) {
+ Class<? extends ReportletConf> result = null;
+
+ ReportletConfClass annotation = reportletClass.getAnnotation(ReportletConfClass.class);
+ if (annotation != null) {
+ result = annotation.value();
+ }
+
+ return result;
+ }
+
+ public Class<Reportlet> findReportletClassHavingConfClass(final Class<? extends ReportletConf> reportletConfClass) {
+ Class<Reportlet> result = null;
+ for (Class<Reportlet> reportletClass : getAllReportletClasses()) {
+ Class<? extends ReportletConf> found = getReportletConfClass(reportletClass);
+ if (found != null && found.equals(reportletConfClass)) {
+ result = reportletClass;
+ }
+ }
+
+ return result;
+ }
+
+ public void getReport(final Report report, final ReportTO reportTO) {
+ BeanUtils.copyProperties(reportTO, report, IGNORE_REPORT_PROPERTIES);
+ report.getReportletConfs().clear();
+ for (ReportletConf conf : reportTO.getReportletConfs()) {
+ report.addReportletConf(conf);
+ }
+ }
+
+ public ReportTO getReportTO(final Report report) {
+ ReportTO reportTO = new ReportTO();
+ reportTO.setId(report.getKey());
+ BeanUtils.copyProperties(report, reportTO, IGNORE_REPORT_PROPERTIES);
+
+ copyReportletConfs(report, reportTO);
+
+ ReportExec latestExec = reportExecDAO.findLatestStarted(report);
+ reportTO.setLatestExecStatus(latestExec == null
+ ? ""
+ : latestExec.getStatus());
+
+ reportTO.setStartDate(latestExec == null
+ ? null
+ : latestExec.getStartDate());
+
+ reportTO.setEndDate(latestExec == null
+ ? null
+ : latestExec.getEndDate());
+
+ for (ReportExec reportExec : report.getExecs()) {
+ reportTO.getExecutions().add(getReportExecTO(reportExec));
+ }
+
+ String triggerName = JobInstanceLoader.getTriggerName(JobInstanceLoader.getJobName(report));
+
+ Trigger trigger;
+ try {
+ trigger = scheduler.getScheduler().getTrigger(new TriggerKey(triggerName, Scheduler.DEFAULT_GROUP));
+ } catch (SchedulerException e) {
+ LOG.warn("While trying to get to " + triggerName, e);
+ trigger = null;
+ }
+
+ if (trigger != null) {
+ reportTO.setLastExec(trigger.getPreviousFireTime());
+ reportTO.setNextExec(trigger.getNextFireTime());
+ }
+
+ return reportTO;
+ }
+
+ private void copyReportletConfs(final Report report, final ReportTO reportTO) {
+ reportTO.getReportletConfs().clear();
+ for (ReportletConf reportletConf : report.getReportletConfs()) {
+ reportTO.getReportletConfs().add((AbstractReportletConf) reportletConf);
+ }
+ }
+
+ public ReportExecTO getReportExecTO(final ReportExec execution) {
+ ReportExecTO executionTO = new ReportExecTO();
+ executionTO.setKey(execution.getKey());
+ BeanUtils.copyProperties(execution, executionTO, IGNORE_REPORT_EXECUTION_PROPERTIES);
+ if (execution.getKey() != null) {
+ executionTO.setKey(execution.getKey());
+ }
+ executionTO.setReport(execution.getReport().getKey());
+
+ return executionTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ResourceDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ResourceDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ResourceDataBinder.java
new file mode 100644
index 0000000..b307eee
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/ResourceDataBinder.java
@@ -0,0 +1,389 @@
+/*
+ * 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.server.logic.data;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.persistence.api.dao.NotFoundException;
+import org.apache.syncope.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.persistence.api.entity.ConnInstance;
+import org.apache.syncope.persistence.api.entity.EntityFactory;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+import org.apache.syncope.persistence.api.entity.Mapping;
+import org.apache.syncope.persistence.api.entity.MappingItem;
+import org.apache.syncope.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.persistence.api.entity.role.RMapping;
+import org.apache.syncope.persistence.api.entity.role.RMappingItem;
+import org.apache.syncope.persistence.api.entity.user.UMapping;
+import org.apache.syncope.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.server.utils.jexl.JexlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ResourceDataBinder {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ResourceDataBinder.class);
+
+ private static final String[] MAPPINGITEM_IGNORE_PROPERTIES = { "key", "mapping" };
+
+ @Autowired
+ private ConnInstanceDAO connInstanceDAO;
+
+ @Autowired
+ private PolicyDAO policyDAO;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ public ExternalResource create(final ResourceTO resourceTO) {
+ return update(entityFactory.newEntity(ExternalResource.class), resourceTO);
+ }
+
+ public ExternalResource update(final ExternalResource resource, final ResourceTO resourceTO) {
+ if (resourceTO == null) {
+ return null;
+ }
+
+ resource.setKey(resourceTO.getKey());
+
+ if (resourceTO.getConnectorId() != null) {
+ ConnInstance connector = connInstanceDAO.find(resourceTO.getConnectorId());
+ resource.setConnector(connector);
+
+ if (!connector.getResources().contains(resource)) {
+ connector.addResource(resource);
+ }
+ }
+
+ resource.setEnforceMandatoryCondition(resourceTO.isEnforceMandatoryCondition());
+
+ resource.setPropagationPrimary(resourceTO.isPropagationPrimary());
+
+ resource.setPropagationPriority(resourceTO.getPropagationPriority());
+
+ resource.setRandomPwdIfNotProvided(resourceTO.isRandomPwdIfNotProvided());
+
+ resource.setPropagationMode(resourceTO.getPropagationMode());
+
+ if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
+ resource.setUmapping(null);
+ } else {
+ UMapping mapping = entityFactory.newEntity(UMapping.class);
+ mapping.setResource(resource);
+ resource.setUmapping(mapping);
+ populateMapping(resourceTO.getUmapping(), mapping, entityFactory.newEntity(UMappingItem.class));
+ }
+ if (resourceTO.getRmapping() == null || resourceTO.getRmapping().getItems().isEmpty()) {
+ resource.setRmapping(null);
+ } else {
+ RMapping mapping = entityFactory.newEntity(RMapping.class);
+ mapping.setResource(resource);
+ resource.setRmapping(mapping);
+ populateMapping(resourceTO.getRmapping(), mapping, entityFactory.newEntity(RMappingItem.class));
+ }
+
+ resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
+ resource.setUpdateTraceLevel(resourceTO.getUpdateTraceLevel());
+ resource.setDeleteTraceLevel(resourceTO.getDeleteTraceLevel());
+ resource.setSyncTraceLevel(resourceTO.getSyncTraceLevel());
+
+ resource.setPasswordPolicy(resourceTO.getPasswordPolicy() == null
+ ? null : (PasswordPolicy) policyDAO.find(resourceTO.getPasswordPolicy()));
+
+ resource.setAccountPolicy(resourceTO.getAccountPolicy() == null
+ ? null : (AccountPolicy) policyDAO.find(resourceTO.getAccountPolicy()));
+
+ resource.setSyncPolicy(resourceTO.getSyncPolicy() == null
+ ? null : (SyncPolicy) policyDAO.find(resourceTO.getSyncPolicy()));
+
+ resource.setConnInstanceConfiguration(new HashSet<>(resourceTO.getConnConfProperties()));
+
+ if (resourceTO.getUsyncToken() == null) {
+ resource.setUsyncToken(null);
+ }
+ if (resourceTO.getRsyncToken() == null) {
+ resource.setRsyncToken(null);
+ }
+
+ resource.getPropagationActionsClassNames().clear();
+ resource.getPropagationActionsClassNames().addAll(resourceTO.getPropagationActionsClassNames());
+
+ return resource;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void populateMapping(final MappingTO mappingTO, final Mapping mapping, final MappingItem prototype) {
+ mapping.setAccountLink(mappingTO.getAccountLink());
+
+ for (MappingItem item : getMappingItems(mappingTO.getItems(), prototype)) {
+ item.setMapping(mapping);
+ if (item.isAccountid()) {
+ mapping.setAccountIdItem(item);
+ } else if (item.isPassword()) {
+ ((UMapping) mapping).setPasswordItem((UMappingItem) item);
+ } else {
+ mapping.addItem(item);
+ }
+ }
+ }
+
+ private Set<MappingItem> getMappingItems(final Collection<MappingItemTO> itemTOs, final MappingItem prototype) {
+ Set<MappingItem> items = new HashSet<>(itemTOs.size());
+ for (MappingItemTO itemTO : itemTOs) {
+ items.add(getMappingItem(itemTO, prototype));
+ }
+
+ return items;
+ }
+
+ private MappingItem getMappingItem(final MappingItemTO itemTO, final MappingItem prototype) {
+ if (itemTO == null || itemTO.getIntMappingType() == null) {
+ LOG.error("Null mappingTO provided");
+ return null;
+ }
+
+ SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+ SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
+ ClientExceptionType.RequiredValuesMissing);
+
+ if (itemTO.getIntAttrName() == null) {
+ if (IntMappingType.getEmbedded().contains(itemTO.getIntMappingType())) {
+ itemTO.setIntAttrName(itemTO.getIntMappingType().toString());
+ } else {
+ requiredValuesMissing.getElements().add("intAttrName");
+ }
+ }
+
+ // Throw composite exception if there is at least one element set
+ // in the composing exceptions
+ if (!requiredValuesMissing.isEmpty()) {
+ scce.addException(requiredValuesMissing);
+ }
+
+ // no mandatory condition implies mandatory condition false
+ if (!JexlUtil.isExpressionValid(itemTO.getMandatoryCondition() == null
+ ? "false" : itemTO.getMandatoryCondition())) {
+
+ SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
+ ClientExceptionType.InvalidValues);
+
+ invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
+
+ scce.addException(invalidMandatoryCondition);
+ }
+
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
+ MappingItem item = SerializationUtils.clone(prototype);
+ BeanUtils.copyProperties(itemTO, item, MAPPINGITEM_IGNORE_PROPERTIES);
+ return item;
+ }
+
+ public ConnInstance getConnInstance(final ExternalResource resource) {
+ final ConnInstance connInstanceClone = SerializationUtils.clone(resource.getConnector());
+ return getConnInstance(connInstanceClone, resource.getConnInstanceConfiguration());
+ }
+
+ public ConnInstance getConnInstance(final ResourceTO resourceTO) {
+ ConnInstance connInstance = connInstanceDAO.find(resourceTO.getConnectorId());
+ if (connInstance == null) {
+ throw new NotFoundException("Connector '" + resourceTO.getConnectorId() + "'");
+ }
+
+ final ConnInstance connInstanceClone = SerializationUtils.clone(connInstance);
+ return getConnInstance(connInstanceClone, resourceTO.getConnConfProperties());
+ }
+
+ private ConnInstance getConnInstance(final ConnInstance connInstance, final Set<ConnConfProperty> overridden) {
+ final Set<ConnConfProperty> configuration = new HashSet<>();
+ final Map<String, ConnConfProperty> overridable = new HashMap<>();
+
+ // add not overridable properties
+ for (ConnConfProperty prop : connInstance.getConfiguration()) {
+ if (prop.isOverridable()) {
+ overridable.put(prop.getSchema().getName(), prop);
+ } else {
+ configuration.add(prop);
+ }
+ }
+
+ // add overridden properties
+ for (ConnConfProperty prop : overridden) {
+ if (overridable.containsKey(prop.getSchema().getName()) && !prop.getValues().isEmpty()) {
+ configuration.add(prop);
+ overridable.remove(prop.getSchema().getName());
+ }
+ }
+
+ // add overridable properties not overridden
+ configuration.addAll(overridable.values());
+
+ connInstance.setConfiguration(configuration);
+
+ return connInstance;
+ }
+
+ public List<ResourceTO> getResourceTOs(final Collection<? extends ExternalResource> resources) {
+ List<ResourceTO> resourceTOs = new ArrayList<>();
+ for (ExternalResource resource : resources) {
+ resourceTOs.add(getResourceTO(resource));
+ }
+
+ return resourceTOs;
+ }
+
+ public ResourceTO getResourceTO(final ExternalResource resource) {
+ if (resource == null) {
+ return null;
+ }
+
+ ResourceTO resourceTO = new ResourceTO();
+
+ // set sys info
+ resourceTO.setCreator(resource.getCreator());
+ resourceTO.setCreationDate(resource.getCreationDate());
+ resourceTO.setLastModifier(resource.getLastModifier());
+ resourceTO.setLastChangeDate(resource.getLastChangeDate());
+
+ // set the resource name
+ resourceTO.setKey(resource.getKey());
+
+ // set the connector instance
+ ConnInstance connector = resource.getConnector();
+
+ resourceTO.setConnectorId(connector == null ? null : connector.getKey());
+ resourceTO.setConnectorDisplayName(connector == null ? null : connector.getDisplayName());
+
+ // set the mappings
+ if (resource.getUmapping() != null) {
+ MappingTO mappingTO = new MappingTO();
+ resourceTO.setUmapping(mappingTO);
+ populateMappingTO(resource.getUmapping(), mappingTO);
+ }
+ if (resource.getRmapping() != null) {
+ MappingTO mappingTO = new MappingTO();
+ resourceTO.setRmapping(mappingTO);
+ populateMappingTO(resource.getRmapping(), mappingTO);
+ }
+
+ resourceTO.setEnforceMandatoryCondition(resource.isEnforceMandatoryCondition());
+
+ resourceTO.setPropagationPrimary(resource.isPropagationPrimary());
+
+ resourceTO.setPropagationPriority(resource.getPropagationPriority());
+
+ resourceTO.setRandomPwdIfNotProvided(resource.isRandomPwdIfNotProvided());
+
+ resourceTO.setPropagationMode(resource.getPropagationMode());
+
+ resourceTO.setCreateTraceLevel(resource.getCreateTraceLevel());
+ resourceTO.setUpdateTraceLevel(resource.getUpdateTraceLevel());
+ resourceTO.setDeleteTraceLevel(resource.getDeleteTraceLevel());
+ resourceTO.setSyncTraceLevel(resource.getSyncTraceLevel());
+
+ resourceTO.setPasswordPolicy(resource.getPasswordPolicy() == null
+ ? null : resource.getPasswordPolicy().getKey());
+
+ resourceTO.setAccountPolicy(resource.getAccountPolicy() == null
+ ? null : resource.getAccountPolicy().getKey());
+
+ resourceTO.setSyncPolicy(resource.getSyncPolicy() == null
+ ? null : resource.getSyncPolicy().getKey());
+
+ resourceTO.getConnConfProperties().addAll(resource.getConnInstanceConfiguration());
+
+ resourceTO.setUsyncToken(resource.getSerializedUSyncToken());
+ resourceTO.setRsyncToken(resource.getSerializedRSyncToken());
+
+ resourceTO.getPropagationActionsClassNames().addAll(resource.getPropagationActionsClassNames());
+
+ return resourceTO;
+ }
+
+ private void populateMappingTO(final Mapping<?> mapping, final MappingTO mappingTO) {
+ mappingTO.setAccountLink(mapping.getAccountLink());
+
+ for (MappingItemTO itemTO : getMappingItemTOs(mapping.getItems())) {
+ if (itemTO.isAccountid()) {
+ mappingTO.setAccountIdItem(itemTO);
+ } else if (itemTO.isPassword()) {
+ mappingTO.setPasswordItem(itemTO);
+ } else {
+ mappingTO.addItem(itemTO);
+ }
+ }
+ }
+
+ private Set<MappingItemTO> getMappingItemTOs(final Collection<? extends MappingItem> items) {
+ Set<MappingItemTO> mappingTOs = new HashSet<>();
+ for (MappingItem item : items) {
+ LOG.debug("Asking for TO for {}", item);
+ mappingTOs.add(getMappingItemTO(item));
+ }
+
+ LOG.debug("Collected TOs: {}", mappingTOs);
+
+ return mappingTOs;
+ }
+
+ private MappingItemTO getMappingItemTO(final MappingItem item) {
+ if (item == null) {
+ LOG.error("Provided null mapping");
+
+ return null;
+ }
+
+ MappingItemTO itemTO = new MappingItemTO();
+
+ BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
+
+ itemTO.setKey(item.getKey());
+
+ LOG.debug("Obtained SchemaMappingTO {}", itemTO);
+
+ return itemTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/RoleDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/RoleDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/RoleDataBinder.java
new file mode 100644
index 0000000..d8dc0df
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/RoleDataBinder.java
@@ -0,0 +1,429 @@
+/*
+ * 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.server.logic.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.persistence.api.dao.RoleDAO;
+import org.apache.syncope.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.persistence.api.entity.AttrTemplate;
+import org.apache.syncope.persistence.api.entity.Entitlement;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+import org.apache.syncope.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.persistence.api.entity.Schema;
+import org.apache.syncope.persistence.api.entity.membership.MDerAttrTemplate;
+import org.apache.syncope.persistence.api.entity.membership.MDerSchema;
+import org.apache.syncope.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.persistence.api.entity.membership.MVirSchema;
+import org.apache.syncope.persistence.api.entity.membership.Membership;
+import org.apache.syncope.persistence.api.entity.role.RDerAttr;
+import org.apache.syncope.persistence.api.entity.role.RDerAttrTemplate;
+import org.apache.syncope.persistence.api.entity.role.RDerSchema;
+import org.apache.syncope.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.persistence.api.entity.role.RPlainAttrTemplate;
+import org.apache.syncope.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.persistence.api.entity.role.RVirAttr;
+import org.apache.syncope.persistence.api.entity.role.RVirAttrTemplate;
+import org.apache.syncope.persistence.api.entity.role.RVirSchema;
+import org.apache.syncope.persistence.api.entity.role.Role;
+import org.apache.syncope.persistence.api.entity.user.User;
+import org.apache.syncope.provisioning.api.propagation.PropagationByResource;
+import org.apache.syncope.server.utils.ConnObjectUtil;
+import org.apache.syncope.provisioning.api.WorkflowResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Transactional(rollbackFor = { Throwable.class })
+public class RoleDataBinder extends AbstractAttributableDataBinder {
+
+ @Autowired
+ private RoleDAO roleDAO;
+
+ @Autowired
+ private ConnObjectUtil connObjectUtil;
+
+ @Autowired
+ private EntitlementDAO entitlementDAO;
+
+ @Transactional(readOnly = true)
+ public List<WorkflowResult<Long>> getUsersOnResourcesOnlyBecauseOfRole(final Long roleId) {
+ Role role = roleDAO.authFetchRole(roleId);
+
+ List<WorkflowResult<Long>> result = new ArrayList<WorkflowResult<Long>>();
+
+ for (Membership membership : roleDAO.findMemberships(role)) {
+ User user = membership.getUser();
+
+ PropagationByResource propByRes = new PropagationByResource();
+ for (ExternalResource resource : role.getResources()) {
+ if (!user.getOwnResources().contains(resource)) {
+ propByRes.add(ResourceOperation.DELETE, resource.getKey());
+ }
+
+ if (!propByRes.isEmpty()) {
+ result.add(new WorkflowResult<Long>(user.getKey(), propByRes, Collections.<String>emptySet()));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private <T extends AttrTemplate<S>, S extends Schema> void setAttrTemplates(
+ final Role role, final List<String> schemaNames,
+ final Class<T> templateClass, final Class<S> schemaClass) {
+
+ List<T> toRemove = new ArrayList<T>();
+ for (T template : role.getAttrTemplates(templateClass)) {
+ if (!schemaNames.contains(template.getSchema().getKey())) {
+ toRemove.add(template);
+ }
+ }
+ role.getAttrTemplates(templateClass).removeAll(toRemove);
+
+ for (String schemaName : schemaNames) {
+ if (role.getAttrTemplate(templateClass, schemaName) == null) {
+ S schema = getSchema(schemaName, schemaClass);
+ if (schema != null) {
+ try {
+ T template = templateClass.newInstance();
+ template.setSchema(schema);
+ template.setOwner(role);
+ role.getAttrTemplates(templateClass).add(template);
+ } catch (Exception e) {
+ LOG.error("Could not create template for {}", templateClass, e);
+ }
+ }
+ }
+ }
+ }
+
+ public Role create(final Role role, final RoleTO roleTO) {
+ role.setInheritOwner(roleTO.isInheritOwner());
+
+ role.setInheritPlainAttrs(roleTO.isInheritAttrs());
+ role.setInheritDerAttrs(roleTO.isInheritDerAttrs());
+ role.setInheritVirAttrs(roleTO.isInheritVirAttrs());
+
+ role.setInheritTemplates(roleTO.isInheritTemplates());
+
+ role.setInheritPasswordPolicy(roleTO.isInheritPasswordPolicy());
+ role.setInheritAccountPolicy(roleTO.isInheritAccountPolicy());
+
+ SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+ // name and parent
+ SyncopeClientException invalidRoles = SyncopeClientException.build(ClientExceptionType.InvalidRoles);
+ if (roleTO.getName() == null) {
+ LOG.error("No name specified for this role");
+
+ invalidRoles.getElements().add("No name specified for this role");
+ } else {
+ role.setName(roleTO.getName());
+ }
+ Long parentRoleKey = null;
+ if (roleTO.getParent() != 0) {
+ Role parentRole = roleDAO.find(roleTO.getParent());
+ if (parentRole == null) {
+ LOG.error("Could not find role with id " + roleTO.getParent());
+
+ invalidRoles.getElements().add(String.valueOf(roleTO.getParent()));
+ scce.addException(invalidRoles);
+ } else {
+ role.setParent(parentRole);
+ parentRoleKey = role.getParent().getKey();
+ }
+ }
+
+ Role otherRole = roleDAO.find(roleTO.getName(), parentRoleKey);
+ if (otherRole != null) {
+ LOG.error("Another role exists with the same name " + "and the same parent role: " + otherRole);
+
+ invalidRoles.getElements().add(roleTO.getName());
+ }
+
+ // attribute templates
+ setAttrTemplates(role, roleTO.getRAttrTemplates(), RPlainAttrTemplate.class, RPlainSchema.class);
+ setAttrTemplates(role, roleTO.getRDerAttrTemplates(), RDerAttrTemplate.class, RDerSchema.class);
+ setAttrTemplates(role, roleTO.getRVirAttrTemplates(), RVirAttrTemplate.class, RVirSchema.class);
+ setAttrTemplates(role, roleTO.getMAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class);
+ setAttrTemplates(role, roleTO.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class);
+ setAttrTemplates(role, roleTO.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
+
+ // attributes, derived attributes, virtual attributes and resources
+ fill(role, roleTO, attrUtilFactory.getInstance(AttributableType.ROLE), scce);
+
+ // entitlements
+ for (String entitlementName : roleTO.getEntitlements()) {
+ Entitlement entitlement = entitlementDAO.find(entitlementName);
+ if (entitlement == null) {
+ LOG.warn("Ignoring invalid entitlement {}", entitlementName);
+ } else {
+ role.addEntitlement(entitlement);
+ }
+ }
+
+ // owner
+ if (roleTO.getUserOwner() != null) {
+ User owner = userDAO.find(roleTO.getUserOwner());
+ if (owner == null) {
+ LOG.warn("Ignoring invalid user specified as owner: {}", roleTO.getUserOwner());
+ } else {
+ role.setUserOwner(owner);
+ }
+ }
+ if (roleTO.getRoleOwner() != null) {
+ Role owner = roleDAO.find(roleTO.getRoleOwner());
+ if (owner == null) {
+ LOG.warn("Ignoring invalid role specified as owner: {}", roleTO.getRoleOwner());
+ } else {
+ role.setRoleOwner(owner);
+ }
+ }
+
+ // policies
+ if (roleTO.getPasswordPolicy() != null) {
+ role.setPasswordPolicy((PasswordPolicy) policyDAO.find(roleTO.getPasswordPolicy()));
+ }
+ if (roleTO.getAccountPolicy() != null) {
+ role.setAccountPolicy((AccountPolicy) policyDAO.find(roleTO.getAccountPolicy()));
+ }
+
+ return role;
+ }
+
+ public PropagationByResource update(final Role role, final RoleMod roleMod) {
+ PropagationByResource propByRes = new PropagationByResource();
+
+ SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+ Set<String> currentResources = role.getResourceNames();
+
+ // name
+ SyncopeClientException invalidRoles = SyncopeClientException.build(ClientExceptionType.InvalidRoles);
+ if (roleMod.getName() != null) {
+ Role otherRole = roleDAO.find(roleMod.getName(),
+ role.getParent() == null ? null : role.getParent().getKey());
+ if (otherRole == null || role.equals(otherRole)) {
+ if (!roleMod.getName().equals(role.getName())) {
+ propByRes.addAll(ResourceOperation.UPDATE, currentResources);
+ for (String resource : currentResources) {
+ propByRes.addOldAccountId(resource, role.getName());
+ }
+
+ role.setName(roleMod.getName());
+ }
+ } else {
+ LOG.error("Another role exists with the same name and the same parent role: " + otherRole);
+
+ invalidRoles.getElements().add(roleMod.getName());
+ scce.addException(invalidRoles);
+ }
+ }
+
+ if (roleMod.getInheritOwner() != null) {
+ role.setInheritOwner(roleMod.getInheritOwner());
+ }
+
+ if (roleMod.getInheritTemplates() != null) {
+ role.setInheritTemplates(roleMod.getInheritTemplates());
+ }
+
+ if (roleMod.getInheritPlainAttrs() != null) {
+ role.setInheritPlainAttrs(roleMod.getInheritPlainAttrs());
+ }
+ if (roleMod.getInheritDerAttrs() != null) {
+ role.setInheritDerAttrs(roleMod.getInheritDerAttrs());
+ }
+ if (roleMod.getInheritVirAttrs() != null) {
+ role.setInheritVirAttrs(roleMod.getInheritVirAttrs());
+ }
+
+ if (roleMod.getInheritPasswordPolicy() != null) {
+ role.setInheritPasswordPolicy(roleMod.getInheritPasswordPolicy());
+ }
+ if (roleMod.getInheritAccountPolicy() != null) {
+ role.setInheritAccountPolicy(roleMod.getInheritAccountPolicy());
+ }
+
+ // entitlements
+ if (roleMod.isModEntitlements()) {
+ role.getEntitlements().clear();
+ for (String entitlementName : roleMod.getEntitlements()) {
+ Entitlement entitlement = entitlementDAO.find(entitlementName);
+ if (entitlement == null) {
+ LOG.warn("Ignoring invalid entitlement {}", entitlementName);
+ } else {
+ role.addEntitlement(entitlement);
+ }
+ }
+ }
+
+ // attribute templates
+ if (roleMod.isModRAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getRPlainAttrTemplates(), RPlainAttrTemplate.class, RPlainSchema.class);
+ }
+ if (roleMod.isModRDerAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getRDerAttrTemplates(), RDerAttrTemplate.class, RDerSchema.class);
+ }
+ if (roleMod.isModRVirAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getRVirAttrTemplates(), RVirAttrTemplate.class, RVirSchema.class);
+ }
+ if (roleMod.isModMAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getMPlainAttrTemplates(), MPlainAttrTemplate.class, MPlainSchema.class);
+ }
+ if (roleMod.isModMDerAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getMDerAttrTemplates(), MDerAttrTemplate.class, MDerSchema.class);
+ }
+ if (roleMod.isModMVirAttrTemplates()) {
+ setAttrTemplates(role, roleMod.getMVirAttrTemplates(), MVirAttrTemplate.class, MVirSchema.class);
+ }
+
+ // policies
+ if (roleMod.getPasswordPolicy() != null) {
+ role.setPasswordPolicy(roleMod.getPasswordPolicy().getKey() == null
+ ? null
+ : (PasswordPolicy) policyDAO.find(roleMod.getPasswordPolicy().getKey()));
+ }
+ if (roleMod.getAccountPolicy() != null) {
+ role.setAccountPolicy(roleMod.getAccountPolicy().getKey() == null
+ ? null
+ : (AccountPolicy) policyDAO.find(roleMod.getAccountPolicy().getKey()));
+ }
+
+ // owner
+ if (roleMod.getUserOwner() != null) {
+ role.setUserOwner(roleMod.getUserOwner().getKey() == null
+ ? null
+ : userDAO.find(roleMod.getUserOwner().getKey()));
+ }
+ if (roleMod.getRoleOwner() != null) {
+ role.setRoleOwner(roleMod.getRoleOwner().getKey() == null
+ ? null
+ : roleDAO.find(roleMod.getRoleOwner().getKey()));
+ }
+
+ // attributes, derived attributes, virtual attributes and resources
+ propByRes.merge(fill(role, roleMod, attrUtilFactory.getInstance(AttributableType.ROLE), scce));
+
+ return propByRes;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Transactional(readOnly = true)
+ public RoleTO getRoleTO(final Role role) {
+ connObjectUtil.retrieveVirAttrValues(role, attrUtilFactory.getInstance(AttributableType.ROLE));
+
+ RoleTO roleTO = new RoleTO();
+
+ // set sys info
+ roleTO.setCreator(role.getCreator());
+ roleTO.setCreationDate(role.getCreationDate());
+ roleTO.setLastModifier(role.getLastModifier());
+ roleTO.setLastChangeDate(role.getLastChangeDate());
+
+ roleTO.setKey(role.getKey());
+ roleTO.setName(role.getName());
+
+ roleTO.setInheritOwner(role.isInheritOwner());
+
+ roleTO.setInheritTemplates(role.isInheritTemplates());
+
+ roleTO.setInheritAttrs(role.isInheritPlainAttrs());
+ roleTO.setInheritDerAttrs(role.isInheritDerAttrs());
+ roleTO.setInheritVirAttrs(role.isInheritVirAttrs());
+
+ roleTO.setInheritPasswordPolicy(role.isInheritPasswordPolicy());
+ roleTO.setInheritAccountPolicy(role.isInheritAccountPolicy());
+
+ if (role.getParent() != null) {
+ roleTO.setParent(role.getParent().getKey());
+ }
+
+ if (role.getUserOwner() != null) {
+ roleTO.setUserOwner(role.getUserOwner().getKey());
+ }
+ if (role.getRoleOwner() != null) {
+ roleTO.setRoleOwner(role.getRoleOwner().getKey());
+ }
+
+ // -------------------------
+ // Retrieve all [derived/virtual] attributes (inherited and not)
+ // -------------------------
+ final List<? extends RPlainAttr> allAttributes = role.findLastInheritedAncestorPlainAttrs();
+
+ final List<? extends RDerAttr> allDerAttributes = role.findLastInheritedAncestorDerAttrs();
+
+ final List<? extends RVirAttr> allVirAttributes = role.findLastInheritedAncestorVirAttrs();
+ // -------------------------
+
+ fillTO(roleTO, allAttributes, allDerAttributes, allVirAttributes, role.getResources());
+
+ for (Entitlement entitlement : role.getEntitlements()) {
+ roleTO.getEntitlements().add(entitlement.getKey());
+ }
+
+ for (RPlainAttrTemplate template : role.findInheritedTemplates(RPlainAttrTemplate.class)) {
+ roleTO.getRAttrTemplates().add(template.getSchema().getKey());
+ }
+ for (RDerAttrTemplate template : role.findInheritedTemplates(RDerAttrTemplate.class)) {
+ roleTO.getRDerAttrTemplates().add(template.getSchema().getKey());
+ }
+ for (RVirAttrTemplate template : role.findInheritedTemplates(RVirAttrTemplate.class)) {
+ roleTO.getRVirAttrTemplates().add(template.getSchema().getKey());
+ }
+ for (MPlainAttrTemplate template : role.findInheritedTemplates(MPlainAttrTemplate.class)) {
+ roleTO.getMAttrTemplates().add(template.getSchema().getKey());
+ }
+ for (MDerAttrTemplate template : role.findInheritedTemplates(MDerAttrTemplate.class)) {
+ roleTO.getMDerAttrTemplates().add(template.getSchema().getKey());
+ }
+ for (MVirAttrTemplate template : role.findInheritedTemplates(MVirAttrTemplate.class)) {
+ roleTO.getMVirAttrTemplates().add(template.getSchema().getKey());
+ }
+
+ roleTO.setPasswordPolicy(role.getPasswordPolicy() == null
+ ? null
+ : role.getPasswordPolicy().getKey());
+ roleTO.setAccountPolicy(role.getAccountPolicy() == null
+ ? null
+ : role.getAccountPolicy().getKey());
+
+ return roleTO;
+ }
+
+ @Transactional(readOnly = true)
+ public RoleTO getRoleTO(final Long key) {
+ return getRoleTO(roleDAO.authFetchRole(key));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SchemaDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SchemaDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SchemaDataBinder.java
new file mode 100644
index 0000000..79cb4a5
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SchemaDataBinder.java
@@ -0,0 +1,163 @@
+/*
+ * 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.server.logic.data;
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.persistence.api.entity.DerSchema;
+import org.apache.syncope.persistence.api.entity.PlainAttr;
+import org.apache.syncope.persistence.api.entity.PlainSchema;
+import org.apache.syncope.persistence.api.entity.VirSchema;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.apache.syncope.server.utils.jexl.JexlUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SchemaDataBinder {
+
+ @Autowired
+ private PlainSchemaDAO schemaDAO;
+
+ // --------------- PLAIN -----------------
+ private <T extends PlainSchema> void fill(final T schema, final PlainSchemaTO schemaTO) {
+ if (!JexlUtil.isExpressionValid(schemaTO.getMandatoryCondition())) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidValues);
+ sce.getElements().add(schemaTO.getMandatoryCondition());
+ throw sce;
+ }
+
+ BeanUtils.copyProperties(schemaTO, schema);
+ }
+
+ public <T extends PlainSchema> void create(final PlainSchemaTO schemaTO, final T schema) {
+ fill(schema, schemaTO);
+ }
+
+ public <T extends PlainSchema> void update(final PlainSchemaTO schemaTO, final T schema,
+ final AttributableUtil attributableUtil) {
+
+ SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+ List<PlainAttr> attrs = schemaDAO.findAttrs(schema, attributableUtil.plainAttrClass());
+ if (!attrs.isEmpty()) {
+ if (schema.getType() != schemaTO.getType()) {
+ SyncopeClientException e = SyncopeClientException.build(
+ ClientExceptionType.valueOf("Invalid" + schema.getClass().getSimpleName()));
+ e.getElements().add("Cannot change type since " + schema.getKey() + " has attributes");
+
+ scce.addException(e);
+ }
+ if (schema.isUniqueConstraint() != schemaTO.isUniqueConstraint()) {
+ SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.valueOf("Invalid"
+ + schema.getClass().getSimpleName()));
+ e.getElements().add("Cannot alter unique contraint since " + schema.getKey() + " has attributes");
+
+ scce.addException(e);
+ }
+ }
+
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
+ fill(schema, schemaTO);
+ }
+
+ public <T extends PlainSchema> PlainSchemaTO getSchemaTO(
+ final T schema, final AttributableUtil attributableUtil) {
+
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ BeanUtils.copyProperties(schema, schemaTO);
+
+ return schemaTO;
+ }
+
+ // --------------- DERIVED -----------------
+ private <T extends DerSchema> T populate(final T derSchema, final DerSchemaTO derSchemaTO) {
+ SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+ if (StringUtils.isBlank(derSchemaTO.getExpression())) {
+ SyncopeClientException requiredValuesMissing =
+ SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
+ requiredValuesMissing.getElements().add("expression");
+
+ scce.addException(requiredValuesMissing);
+ } else if (!JexlUtil.isExpressionValid(derSchemaTO.getExpression())) {
+ SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
+ ClientExceptionType.InvalidValues);
+ invalidMandatoryCondition.getElements().add(derSchemaTO.getExpression());
+
+ scce.addException(invalidMandatoryCondition);
+ }
+
+ if (scce.hasExceptions()) {
+ throw scce;
+ }
+
+ BeanUtils.copyProperties(derSchemaTO, derSchema);
+
+ return derSchema;
+ }
+
+ public <T extends DerSchema> T create(final DerSchemaTO derSchemaTO, final T derSchema) {
+ return populate(derSchema, derSchemaTO);
+ }
+
+ public <T extends DerSchema> T update(final DerSchemaTO derSchemaTO, final T derSchema) {
+ return populate(derSchema, derSchemaTO);
+ }
+
+ public <T extends DerSchema> DerSchemaTO getDerSchemaTO(final T derSchema) {
+ DerSchemaTO derSchemaTO = new DerSchemaTO();
+ BeanUtils.copyProperties(derSchema, derSchemaTO);
+
+ return derSchemaTO;
+ }
+
+ // --------------- VIRTUAL -----------------
+ private <T extends VirSchema> T fill(final T virSchema, final VirSchemaTO virSchemaTO) {
+ BeanUtils.copyProperties(virSchemaTO, virSchema);
+
+ return virSchema;
+ }
+
+ public <T extends VirSchema> T create(final VirSchemaTO virSchemaTO, final T virSchema) {
+ return fill(virSchema, virSchemaTO);
+ }
+
+ public <T extends VirSchema> T update(final VirSchemaTO virSchemaTO, final T virSchema) {
+ return fill(virSchema, virSchemaTO);
+ }
+
+ public <T extends VirSchema> VirSchemaTO getVirSchemaTO(final T virSchema) {
+ VirSchemaTO virSchemaTO = new VirSchemaTO();
+ BeanUtils.copyProperties(virSchema, virSchemaTO);
+
+ return virSchemaTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/99369c31/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SecurityQuestionDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SecurityQuestionDataBinder.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SecurityQuestionDataBinder.java
new file mode 100644
index 0000000..b8dce1d
--- /dev/null
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/data/SecurityQuestionDataBinder.java
@@ -0,0 +1,51 @@
+/*
+ * 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.server.logic.data;
+
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.persistence.api.entity.EntityFactory;
+import org.apache.syncope.persistence.api.entity.user.SecurityQuestion;
+import org.apache.syncope.server.spring.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SecurityQuestionDataBinder {
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ public SecurityQuestionTO getSecurityQuestionTO(final SecurityQuestion securityQuestion) {
+ SecurityQuestionTO securityQuestionTO = new SecurityQuestionTO();
+
+ BeanUtils.copyProperties(securityQuestion, securityQuestionTO);
+
+ return securityQuestionTO;
+ }
+
+ public SecurityQuestion create(final SecurityQuestionTO securityQuestionTO) {
+ SecurityQuestion result = entityFactory.newEntity(SecurityQuestion.class);
+ update(result, securityQuestionTO);
+ return result;
+ }
+
+ public void update(final SecurityQuestion securityQuestion, final SecurityQuestionTO securityQuestionTO) {
+ BeanUtils.copyProperties(securityQuestionTO, securityQuestion, "key");
+ }
+}