1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.data;
20
21 import java.text.ParseException;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
28 import java.util.stream.Stream;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
31 import org.apache.syncope.common.lib.SyncopeClientException;
32 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
33 import org.apache.syncope.common.lib.to.Item;
34 import org.apache.syncope.common.lib.to.ItemContainer;
35 import org.apache.syncope.common.lib.to.Mapping;
36 import org.apache.syncope.common.lib.to.OrgUnit;
37 import org.apache.syncope.common.lib.to.Provision;
38 import org.apache.syncope.common.lib.to.ResourceTO;
39 import org.apache.syncope.common.lib.types.AnyTypeKind;
40 import org.apache.syncope.common.lib.types.ClientExceptionType;
41 import org.apache.syncope.common.lib.types.MappingPurpose;
42 import org.apache.syncope.common.lib.types.SchemaType;
43 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
44 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
45 import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
46 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
47 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
48 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
49 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
50 import org.apache.syncope.core.persistence.api.entity.AnyType;
51 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
52 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
53 import org.apache.syncope.core.persistence.api.entity.DerSchema;
54 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
55 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
56 import org.apache.syncope.core.persistence.api.entity.Implementation;
57 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
58 import org.apache.syncope.core.persistence.api.entity.VirSchema;
59 import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
60 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
61 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
62 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
63 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
64 import org.apache.syncope.core.provisioning.api.IntAttrName;
65 import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
66 import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
67 import org.apache.syncope.core.provisioning.api.jexl.JexlUtils;
68 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
69 import org.identityconnectors.framework.common.objects.ObjectClass;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 public class ResourceDataBinderImpl implements ResourceDataBinder {
74
75 protected static final Logger LOG = LoggerFactory.getLogger(ResourceDataBinder.class);
76
77 protected final AnyTypeDAO anyTypeDAO;
78
79 protected final ConnInstanceDAO connInstanceDAO;
80
81 protected final PolicyDAO policyDAO;
82
83 protected final VirSchemaDAO virSchemaDAO;
84
85 protected final AnyTypeClassDAO anyTypeClassDAO;
86
87 protected final ImplementationDAO implementationDAO;
88
89 protected final PlainSchemaDAO plainSchemaDAO;
90
91 protected final EntityFactory entityFactory;
92
93 protected final IntAttrNameParser intAttrNameParser;
94
95 protected final PropagationTaskExecutor propagationTaskExecutor;
96
97 public ResourceDataBinderImpl(
98 final AnyTypeDAO anyTypeDAO,
99 final ConnInstanceDAO connInstanceDAO,
100 final PolicyDAO policyDAO,
101 final VirSchemaDAO virSchemaDAO,
102 final AnyTypeClassDAO anyTypeClassDAO,
103 final ImplementationDAO implementationDAO,
104 final PlainSchemaDAO plainSchemaDAO,
105 final EntityFactory entityFactory,
106 final IntAttrNameParser intAttrNameParser,
107 final PropagationTaskExecutor propagationTaskExecutor) {
108
109 this.anyTypeDAO = anyTypeDAO;
110 this.connInstanceDAO = connInstanceDAO;
111 this.policyDAO = policyDAO;
112 this.virSchemaDAO = virSchemaDAO;
113 this.anyTypeClassDAO = anyTypeClassDAO;
114 this.implementationDAO = implementationDAO;
115 this.plainSchemaDAO = plainSchemaDAO;
116 this.entityFactory = entityFactory;
117 this.intAttrNameParser = intAttrNameParser;
118 this.propagationTaskExecutor = propagationTaskExecutor;
119 }
120
121 @Override
122 public ExternalResource create(final ResourceTO resourceTO) {
123 return update(entityFactory.newEntity(ExternalResource.class), resourceTO);
124 }
125
126 @Override
127 public ExternalResource update(final ExternalResource resource, final ResourceTO resourceTO) {
128 resource.setKey(resourceTO.getKey());
129
130 if (resourceTO.getConnector() != null) {
131 ConnInstance connector = connInstanceDAO.find(resourceTO.getConnector());
132 resource.setConnector(connector);
133
134 if (!connector.getResources().contains(resource)) {
135 connector.add(resource);
136 }
137 }
138
139 resource.setEnforceMandatoryCondition(resourceTO.isEnforceMandatoryCondition());
140
141 resource.setPropagationPriority(resourceTO.getPropagationPriority());
142
143
144 resourceTO.getProvisions().forEach(provisionTO -> {
145 AnyType anyType = anyTypeDAO.find(provisionTO.getAnyType());
146 if (anyType == null) {
147 LOG.debug("Invalid {} specified {}, ignoring...",
148 AnyType.class.getSimpleName(), provisionTO.getAnyType());
149 } else {
150 Provision provision = resource.getProvisionByAnyType(anyType.getKey()).orElse(null);
151 if (provision == null) {
152 provision = new Provision();
153 provision.setAnyType(anyType.getKey());
154 resource.getProvisions().add(provision);
155 }
156
157 if (provisionTO.getObjectClass() == null) {
158 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidProvision);
159 sce.getElements().add("Null " + ObjectClass.class.getSimpleName());
160 throw sce;
161 }
162 provision.setObjectClass(provisionTO.getObjectClass());
163
164
165 for (String name : provisionTO.getAuxClasses()) {
166 AnyTypeClass anyTypeClass = anyTypeClassDAO.find(name);
167 if (anyTypeClass == null || provision.getAuxClasses().contains(name)) {
168 LOG.warn("Ignoring invalid or already present {}: {}",
169 AnyTypeClass.class.getSimpleName(), name);
170 } else {
171 provision.getAuxClasses().add(anyTypeClass.getKey());
172 }
173 }
174
175 provision.getAuxClasses().
176 removeIf(anyTypeClass -> !provisionTO.getAuxClasses().contains(anyTypeClass));
177
178 provision.setIgnoreCaseMatch(provisionTO.isIgnoreCaseMatch());
179
180 if (StringUtils.isBlank(provisionTO.getUidOnCreate())) {
181 provision.setUidOnCreate(null);
182 } else {
183 PlainSchema uidOnCreate = plainSchemaDAO.find(provisionTO.getUidOnCreate());
184 if (uidOnCreate == null) {
185 LOG.warn("Ignoring invalid schema for uidOnCreate: {}", provisionTO.getUidOnCreate());
186 provision.setUidOnCreate(null);
187 } else {
188 provision.setUidOnCreate(uidOnCreate.getKey());
189 }
190 }
191
192 if (provisionTO.getMapping() == null) {
193 provision.setMapping(null);
194 } else {
195 Mapping mapping = provision.getMapping();
196 if (mapping == null) {
197 mapping = new Mapping();
198 provision.setMapping(mapping);
199 } else {
200 mapping.getItems().clear();
201 }
202
203 AnyTypeClassTO allowedSchemas = new AnyTypeClassTO();
204 Stream.concat(
205 anyType.getClasses().stream(),
206 provision.getAuxClasses().stream().map(anyTypeClassDAO::find)).forEach(anyTypeClass -> {
207
208 allowedSchemas.getPlainSchemas().addAll(anyTypeClass.getPlainSchemas().stream().
209 map(PlainSchema::getKey).collect(Collectors.toList()));
210 allowedSchemas.getDerSchemas().addAll(anyTypeClass.getDerSchemas().stream().
211 map(DerSchema::getKey).collect(Collectors.toList()));
212 allowedSchemas.getVirSchemas().addAll(anyTypeClass.getVirSchemas().stream().
213 map(VirSchema::getKey).collect(Collectors.toList()));
214 });
215
216 populateMapping(
217 resource,
218 provisionTO.getMapping(),
219 mapping,
220 anyType.getKind(),
221 allowedSchemas);
222 }
223
224 if (provisionTO.getVirSchemas().isEmpty()) {
225 for (VirSchema schema : virSchemaDAO.find(resource.getKey(), anyType.getKey())) {
226 virSchemaDAO.delete(schema.getKey());
227 }
228 } else {
229 for (String schemaName : provisionTO.getVirSchemas()) {
230 VirSchema schema = virSchemaDAO.find(schemaName);
231 if (schema == null) {
232 LOG.debug("Invalid {} specified: {}, ignoring...",
233 VirSchema.class.getSimpleName(), schemaName);
234 } else {
235 schema.setResource(resource);
236 schema.setAnyType(anyTypeDAO.find(provision.getAnyType()));
237 }
238 }
239 }
240 }
241 });
242
243
244 for (Iterator<Provision> itor = resource.getProvisions().iterator(); itor.hasNext();) {
245 Provision provision = itor.next();
246 if (resourceTO.getProvision(provision.getAnyType()).isEmpty()) {
247 virSchemaDAO.find(resource.getKey(), provision.getAnyType()).
248 forEach(schema -> virSchemaDAO.delete(schema.getKey()));
249
250 itor.remove();
251 }
252 }
253
254
255 if (resourceTO.getOrgUnit() == null && resource.getOrgUnit() != null) {
256 resource.setOrgUnit(null);
257 } else if (resourceTO.getOrgUnit() != null) {
258 OrgUnit orgUnitTO = resourceTO.getOrgUnit();
259
260 OrgUnit orgUnit = Optional.ofNullable(resource.getOrgUnit()).orElseGet(() -> new OrgUnit());
261
262 if (orgUnitTO.getObjectClass() == null) {
263 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
264 sce.getElements().add("Null " + ObjectClass.class.getSimpleName());
265 throw sce;
266 }
267 orgUnit.setObjectClass(orgUnitTO.getObjectClass());
268
269 orgUnit.setIgnoreCaseMatch(orgUnitTO.isIgnoreCaseMatch());
270
271 if (orgUnitTO.getConnObjectLink() == null) {
272 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidOrgUnit);
273 sce.getElements().add("Null connObjectLink");
274 throw sce;
275 }
276 orgUnit.setConnObjectLink(orgUnitTO.getConnObjectLink());
277
278 SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
279 SyncopeClientException invalidMapping = SyncopeClientException.build(
280 ClientExceptionType.InvalidMapping);
281 SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
282 ClientExceptionType.RequiredValuesMissing);
283
284 orgUnit.getItems().clear();
285 for (Item itemTO : orgUnitTO.getItems()) {
286 if (itemTO == null) {
287 LOG.error("Null {}", Item.class.getSimpleName());
288 invalidMapping.getElements().add("Null " + Item.class.getSimpleName());
289 } else if (itemTO.getIntAttrName() == null) {
290 requiredValuesMissing.getElements().add("intAttrName");
291 scce.addException(requiredValuesMissing);
292 } else {
293 if (!"name".equals(itemTO.getIntAttrName()) && !"fullpath".equals(itemTO.getIntAttrName())) {
294 LOG.error("Only 'name' and 'fullpath' are supported for Realms");
295 invalidMapping.getElements().add("Only 'name' and 'fullpath' are supported for Realms");
296 } else {
297
298 if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
299 ? "false" : itemTO.getMandatoryCondition())) {
300
301 SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
302 ClientExceptionType.InvalidValues);
303 invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
304 scce.addException(invalidMandatoryCondition);
305 }
306
307 Item item = new Item();
308 item.setIntAttrName(itemTO.getIntAttrName());
309 item.setExtAttrName(itemTO.getExtAttrName());
310 item.setPurpose(itemTO.getPurpose());
311 item.setMandatoryCondition(itemTO.getMandatoryCondition());
312 item.setConnObjectKey(itemTO.isConnObjectKey());
313 item.setPassword(itemTO.isPassword());
314 item.setPropagationJEXLTransformer(itemTO.getPropagationJEXLTransformer());
315 item.setPullJEXLTransformer(itemTO.getPullJEXLTransformer());
316
317 itemTO.getTransformers().forEach(transformerKey -> {
318 Implementation transformer = implementationDAO.find(transformerKey);
319 if (transformer == null) {
320 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...",
321 transformerKey);
322 } else {
323 item.getTransformers().add(transformer.getKey());
324 }
325 });
326
327 item.getTransformers().
328 removeIf(implementation -> !itemTO.getTransformers().contains(implementation));
329
330 if (item.isConnObjectKey()) {
331 orgUnit.setConnObjectKeyItem(item);
332 } else {
333 orgUnit.add(item);
334 }
335 }
336 }
337 }
338 if (!invalidMapping.getElements().isEmpty()) {
339 scce.addException(invalidMapping);
340 }
341 if (scce.hasExceptions()) {
342 throw scce;
343 }
344
345 resource.setOrgUnit(orgUnit);
346 }
347
348 resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
349 resource.setUpdateTraceLevel(resourceTO.getUpdateTraceLevel());
350 resource.setDeleteTraceLevel(resourceTO.getDeleteTraceLevel());
351 resource.setProvisioningTraceLevel(resourceTO.getProvisioningTraceLevel());
352
353 resource.setPasswordPolicy(resourceTO.getPasswordPolicy() == null
354 ? null : policyDAO.<PasswordPolicy>find(resourceTO.getPasswordPolicy()));
355
356 resource.setAccountPolicy(resourceTO.getAccountPolicy() == null
357 ? null : policyDAO.<AccountPolicy>find(resourceTO.getAccountPolicy()));
358
359 if (resource.getPropagationPolicy() != null
360 && !resource.getPropagationPolicy().getKey().equals(resourceTO.getPropagationPolicy())) {
361
362 propagationTaskExecutor.expireRetryTemplate(resource.getKey());
363 }
364 resource.setPropagationPolicy(resourceTO.getPropagationPolicy() == null
365 ? null : policyDAO.<PropagationPolicy>find(resourceTO.getPropagationPolicy()));
366
367 resource.setPullPolicy(resourceTO.getPullPolicy() == null
368 ? null : policyDAO.<PullPolicy>find(resourceTO.getPullPolicy()));
369
370 resource.setPushPolicy(resourceTO.getPushPolicy() == null
371 ? null : policyDAO.<PushPolicy>find(resourceTO.getPushPolicy()));
372
373 if (resourceTO.getProvisionSorter() == null) {
374 resource.setProvisionSorter(null);
375 } else {
376 Implementation provisionSorter = implementationDAO.find(resourceTO.getProvisionSorter());
377 if (provisionSorter == null) {
378 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...",
379 resourceTO.getProvisionSorter());
380 } else {
381 resource.setProvisionSorter(provisionSorter);
382 }
383 }
384
385 resource.setConfOverride(new HashSet<>(resourceTO.getConfOverride()));
386
387 resource.setOverrideCapabilities(resourceTO.isOverrideCapabilities());
388 resource.getCapabilitiesOverride().clear();
389 resource.getCapabilitiesOverride().addAll(resourceTO.getCapabilitiesOverride());
390
391 resourceTO.getPropagationActions().forEach(propagationActionKey -> {
392 Implementation propagationAction = implementationDAO.find(propagationActionKey);
393 if (propagationAction == null) {
394 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", propagationActionKey);
395 } else {
396 resource.add(propagationAction);
397 }
398 });
399
400 resource.getPropagationActions().
401 removeIf(propActions -> !resourceTO.getPropagationActions().contains(propActions.getKey()));
402
403 return resource;
404 }
405
406 protected void populateMapping(
407 final ExternalResource resource,
408 final Mapping mappingTO,
409 final Mapping mapping,
410 final AnyTypeKind anyTypeKind,
411 final AnyTypeClassTO allowedSchemas) {
412
413 mapping.setConnObjectLink(mappingTO.getConnObjectLink());
414
415 SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
416 SyncopeClientException invalidMapping = SyncopeClientException.build(ClientExceptionType.InvalidMapping);
417 SyncopeClientException requiredValuesMissing = SyncopeClientException.build(
418 ClientExceptionType.RequiredValuesMissing);
419
420 for (Item itemTO : mappingTO.getItems()) {
421 if (itemTO == null) {
422 LOG.error("Null {}", Item.class.getSimpleName());
423 invalidMapping.getElements().add("Null " + Item.class.getSimpleName());
424 } else if (itemTO.getIntAttrName() == null) {
425 requiredValuesMissing.getElements().add("intAttrName");
426 scce.addException(requiredValuesMissing);
427 } else {
428 IntAttrName intAttrName = null;
429 try {
430 intAttrName = intAttrNameParser.parse(itemTO.getIntAttrName(), anyTypeKind);
431 } catch (ParseException e) {
432 LOG.error("Invalid intAttrName '{}'", itemTO.getIntAttrName(), e);
433 }
434
435 if (intAttrName == null
436 || intAttrName.getSchemaType() == null && intAttrName.getField() == null
437 && intAttrName.getPrivilegesOfApplication() == null) {
438
439 LOG.error("'{}' not existing", itemTO.getIntAttrName());
440 invalidMapping.getElements().add('\'' + itemTO.getIntAttrName() + "' not existing");
441 } else {
442 boolean allowed = true;
443 if (intAttrName.getSchemaType() != null
444 && intAttrName.getEnclosingGroup() == null
445 && intAttrName.getRelatedAnyObject() == null
446 && intAttrName.getRelationshipType() == null
447 && intAttrName.getPrivilegesOfApplication() == null) {
448
449 switch (intAttrName.getSchemaType()) {
450 case PLAIN:
451 allowed = allowedSchemas.getPlainSchemas().contains(intAttrName.getSchema().getKey());
452 break;
453
454 case DERIVED:
455 allowed = allowedSchemas.getDerSchemas().contains(intAttrName.getSchema().getKey());
456 break;
457
458 case VIRTUAL:
459 allowed = allowedSchemas.getVirSchemas().contains(intAttrName.getSchema().getKey());
460 break;
461
462 default:
463 }
464 }
465
466 if (allowed) {
467
468 if (!JexlUtils.isExpressionValid(itemTO.getMandatoryCondition() == null
469 ? "false" : itemTO.getMandatoryCondition())) {
470
471 SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
472 ClientExceptionType.InvalidValues);
473 invalidMandatoryCondition.getElements().add(itemTO.getMandatoryCondition());
474 scce.addException(invalidMandatoryCondition);
475 }
476
477 Item item = new Item();
478 item.setIntAttrName(itemTO.getIntAttrName());
479 item.setExtAttrName(itemTO.getExtAttrName());
480 item.setPurpose(itemTO.getPurpose());
481 item.setMandatoryCondition(itemTO.getMandatoryCondition());
482 item.setConnObjectKey(itemTO.isConnObjectKey());
483 item.setPassword(itemTO.isPassword());
484 item.setPropagationJEXLTransformer(itemTO.getPropagationJEXLTransformer());
485 item.setPullJEXLTransformer(itemTO.getPullJEXLTransformer());
486
487 itemTO.getTransformers().forEach(transformerKey -> {
488 Implementation transformer = implementationDAO.find(transformerKey);
489 if (transformer == null) {
490 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...",
491 transformerKey);
492 } else {
493 item.getTransformers().add(transformer.getKey());
494 }
495 });
496
497 item.getTransformers().
498 removeIf(implementation -> !itemTO.getTransformers().contains(implementation));
499
500 if (item.isConnObjectKey()) {
501 if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) {
502 invalidMapping.getElements().
503 add("Virtual attributes cannot be set as ConnObjectKey");
504 }
505 if ("password".equals(intAttrName.getField())) {
506 invalidMapping.getElements().add(
507 "Password attributes cannot be set as ConnObjectKey");
508 }
509
510 mapping.setConnObjectKeyItem(item);
511 } else {
512 mapping.add(item);
513 }
514
515 if (intAttrName.getEnclosingGroup() != null
516 && item.getPurpose() != MappingPurpose.PROPAGATION) {
517
518 invalidMapping.getElements().add(
519 "Only " + MappingPurpose.PROPAGATION.name()
520 + " allowed when referring to groups");
521 }
522 if (intAttrName.getRelatedAnyObject() != null
523 && item.getPurpose() != MappingPurpose.PROPAGATION) {
524
525 invalidMapping.getElements().add(
526 "Only " + MappingPurpose.PROPAGATION.name()
527 + " allowed when referring to any objects");
528 }
529 if (intAttrName.getPrivilegesOfApplication() != null
530 && item.getPurpose() != MappingPurpose.PROPAGATION) {
531
532 invalidMapping.getElements().add(
533 "Only " + MappingPurpose.PROPAGATION.name()
534 + " allowed when referring to privileges");
535 }
536 if (intAttrName.getSchemaType() == SchemaType.DERIVED
537 && item.getPurpose() != MappingPurpose.PROPAGATION) {
538
539 invalidMapping.getElements().add(
540 "Only " + MappingPurpose.PROPAGATION.name() + " allowed for derived");
541 }
542 if (intAttrName.getSchemaType() == SchemaType.VIRTUAL) {
543 if (item.getPurpose() != MappingPurpose.PROPAGATION) {
544 invalidMapping.getElements().add(
545 "Only " + MappingPurpose.PROPAGATION.name() + " allowed for virtual");
546 }
547
548 VirSchema schema = virSchemaDAO.find(item.getIntAttrName());
549 if (schema != null && schema.getResource().equals(resource)) {
550 invalidMapping.getElements().add(
551 "No need to map virtual schema on linking resource");
552 }
553 }
554 if (intAttrName.getRelatedUser() != null
555 && item.getPurpose() != MappingPurpose.PROPAGATION) {
556
557 invalidMapping.getElements().add(
558 "Only " + MappingPurpose.PROPAGATION.name()
559 + " allowed when referring to users");
560 }
561 if ((intAttrName.getRelationshipType() != null
562 || intAttrName.getRelationshipAnyType() != null)
563 && item.getPurpose() != MappingPurpose.PROPAGATION) {
564
565 invalidMapping.getElements().add(
566 "Only " + MappingPurpose.PROPAGATION.name()
567 + " allowed when referring to relationships");
568 }
569 } else {
570 LOG.error("'{}' not allowed", itemTO.getIntAttrName());
571 invalidMapping.getElements().add('\'' + itemTO.getIntAttrName() + "' not allowed");
572 }
573 }
574 }
575 }
576
577 if (!invalidMapping.getElements().isEmpty()) {
578 scce.addException(invalidMapping);
579 }
580 if (scce.hasExceptions()) {
581 throw scce;
582 }
583 }
584
585 protected void populateItems(final List<Item> items, final ItemContainer containerTO) {
586 items.forEach(item -> {
587 Item itemTO = new Item();
588 itemTO.setIntAttrName(item.getIntAttrName());
589 itemTO.setExtAttrName(item.getExtAttrName());
590 itemTO.setPurpose(item.getPurpose());
591 itemTO.setMandatoryCondition(item.getMandatoryCondition());
592 itemTO.setConnObjectKey(item.isConnObjectKey());
593 itemTO.setPassword(item.isPassword());
594 itemTO.setPropagationJEXLTransformer(item.getPropagationJEXLTransformer());
595 itemTO.setPullJEXLTransformer(item.getPullJEXLTransformer());
596 itemTO.getTransformers().addAll(item.getTransformers());
597
598 if (itemTO.isConnObjectKey()) {
599 containerTO.setConnObjectKeyItem(itemTO);
600 } else {
601 containerTO.add(itemTO);
602 }
603 });
604 }
605
606 @Override
607 public ResourceTO getResourceTO(final ExternalResource resource) {
608 ResourceTO resourceTO = new ResourceTO();
609
610
611 resourceTO.setKey(resource.getKey());
612
613
614 ConnInstance connector = resource.getConnector();
615
616 resourceTO.setConnector(Optional.ofNullable(connector).map(ConnInstance::getKey).orElse(null));
617 resourceTO.setConnectorDisplayName(Optional.ofNullable(connector).
618 map(ConnInstance::getDisplayName).orElse(null));
619
620
621 resource.getProvisions().forEach(provision -> {
622 Provision provisionTO = new Provision();
623 provisionTO.setAnyType(provision.getAnyType());
624 provisionTO.setObjectClass(provision.getObjectClass());
625 provisionTO.getAuxClasses().addAll(provision.getAuxClasses());
626 provisionTO.setSyncToken(provision.getSyncToken());
627 provisionTO.setIgnoreCaseMatch(provision.isIgnoreCaseMatch());
628 provisionTO.setUidOnCreate(provision.getUidOnCreate());
629
630 if (provision.getMapping() != null) {
631 Mapping mappingTO = new Mapping();
632 provisionTO.setMapping(mappingTO);
633 mappingTO.setConnObjectLink(provision.getMapping().getConnObjectLink());
634 populateItems(provision.getMapping().getItems(), mappingTO);
635 }
636
637 resourceTO.getProvisions().add(provisionTO);
638 });
639 resourceTO.getProvisions().
640 forEach(provisionTO -> virSchemaDAO.find(resource.getKey(), provisionTO.getAnyType()).
641 forEach(virSchema -> {
642 provisionTO.getVirSchemas().add(virSchema.getKey());
643 provisionTO.getMapping().getLinkingItems().add(virSchema.asLinkingMappingItem());
644 }));
645
646 if (resource.getOrgUnit() != null) {
647 OrgUnit orgUnit = resource.getOrgUnit();
648
649 OrgUnit orgUnitTO = new OrgUnit();
650 orgUnitTO.setObjectClass(orgUnit.getObjectClass());
651 orgUnitTO.setSyncToken(orgUnit.getSyncToken());
652 orgUnitTO.setIgnoreCaseMatch(orgUnit.isIgnoreCaseMatch());
653 orgUnitTO.setConnObjectLink(orgUnit.getConnObjectLink());
654 populateItems(orgUnit.getItems(), orgUnitTO);
655
656 resourceTO.setOrgUnit(orgUnitTO);
657 }
658
659 resourceTO.setEnforceMandatoryCondition(resource.isEnforceMandatoryCondition());
660
661 resourceTO.setPropagationPriority(resource.getPropagationPriority());
662
663 resourceTO.setCreateTraceLevel(resource.getCreateTraceLevel());
664 resourceTO.setUpdateTraceLevel(resource.getUpdateTraceLevel());
665 resourceTO.setDeleteTraceLevel(resource.getDeleteTraceLevel());
666 resourceTO.setProvisioningTraceLevel(resource.getProvisioningTraceLevel());
667
668 resourceTO.setPasswordPolicy(resource.getPasswordPolicy() == null
669 ? null : resource.getPasswordPolicy().getKey());
670
671 resourceTO.setAccountPolicy(resource.getAccountPolicy() == null
672 ? null : resource.getAccountPolicy().getKey());
673
674 resourceTO.setPropagationPolicy(resource.getPropagationPolicy() == null
675 ? null : resource.getPropagationPolicy().getKey());
676
677 resourceTO.setPullPolicy(resource.getPullPolicy() == null
678 ? null : resource.getPullPolicy().getKey());
679
680 resourceTO.setPushPolicy(resource.getPushPolicy() == null
681 ? null : resource.getPushPolicy().getKey());
682
683 resourceTO.setProvisionSorter(resource.getProvisionSorter() == null
684 ? null : resource.getProvisionSorter().getKey());
685
686 resourceTO.getConfOverride().addAll(resource.getConfOverride());
687 Collections.sort(resourceTO.getConfOverride());
688
689 resourceTO.setOverrideCapabilities(resource.isOverrideCapabilities());
690 resourceTO.getCapabilitiesOverride().addAll(resource.getCapabilitiesOverride());
691
692 resourceTO.getPropagationActions().addAll(
693 resource.getPropagationActions().stream().map(Implementation::getKey).collect(Collectors.toList()));
694
695 return resourceTO;
696 }
697 }