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.lang.reflect.Modifier;
22 import java.util.Optional;
23 import org.apache.commons.lang3.StringUtils;
24 import org.apache.syncope.common.lib.SyncopeClientException;
25 import org.apache.syncope.common.lib.policy.RuleConf;
26 import org.apache.syncope.common.lib.report.ReportConf;
27 import org.apache.syncope.common.lib.to.ImplementationTO;
28 import org.apache.syncope.common.lib.types.ClientExceptionType;
29 import org.apache.syncope.common.lib.types.IdMImplementationType;
30 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
31 import org.apache.syncope.common.lib.types.ImplementationEngine;
32 import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
33 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
34 import org.apache.syncope.core.persistence.api.entity.Implementation;
35 import org.apache.syncope.core.provisioning.api.data.ImplementationDataBinder;
36 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public class ImplementationDataBinderImpl implements ImplementationDataBinder {
41
42 protected static final Logger LOG = LoggerFactory.getLogger(ImplementationDataBinder.class);
43
44 protected final EntityFactory entityFactory;
45
46 public ImplementationDataBinderImpl(final EntityFactory entityFactory) {
47 this.entityFactory = entityFactory;
48 }
49
50 @Override
51 public Implementation create(final ImplementationTO implementationTO) {
52 Implementation implementation = entityFactory.newEntity(Implementation.class);
53 update(implementation, implementationTO);
54 return implementation;
55 }
56
57 @Override
58 public void update(final Implementation implementation, final ImplementationTO implementationTO) {
59 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementation);
60
61 if (implementation.getType() != null && !implementation.getType().equals(implementationTO.getType())) {
62 sce.getElements().add("ImplementationType cannot be changed");
63 throw sce;
64 }
65
66 if (StringUtils.isBlank(implementationTO.getBody())) {
67 sce.getElements().add("No actual implementation provided");
68 throw sce;
69 }
70
71 implementation.setKey(implementationTO.getKey());
72 implementation.setEngine(implementationTO.getEngine());
73 implementation.setType(implementationTO.getType());
74 implementation.setBody(implementationTO.getBody());
75
76 if (implementation.getEngine() == ImplementationEngine.JAVA) {
77 Class<?> baseClazz = Optional.ofNullable(
78 ImplementationTypesHolder.getInstance().getValues().get(implementation.getType())).
79 map(intf -> {
80 try {
81 return Class.forName(intf);
82 } catch (ClassNotFoundException e) {
83 LOG.error("While resolving interface {} for implementation type {}",
84 intf, implementation.getType());
85 return null;
86 }
87 }).
88 orElse(null);
89
90 if (baseClazz == null) {
91 sce.getElements().add("No Java interface found for " + implementation.getType());
92 throw sce;
93 }
94
95 switch (implementation.getType()) {
96 case IdRepoImplementationType.REPORT_DELEGATE:
97 ReportConf conf = POJOHelper.deserialize(implementation.getBody(), ReportConf.class);
98 if (conf == null) {
99 sce.getElements().add("Could not deserialize as " + ReportConf.class.getName());
100 throw sce;
101 }
102 break;
103
104 case IdRepoImplementationType.ACCOUNT_RULE:
105 case IdRepoImplementationType.PASSWORD_RULE:
106 case IdMImplementationType.PULL_CORRELATION_RULE:
107 case IdMImplementationType.PUSH_CORRELATION_RULE:
108 RuleConf rule = POJOHelper.deserialize(implementation.getBody(), RuleConf.class);
109 if (rule == null) {
110 sce.getElements().add("Could not deserialize as neither "
111 + "Account, Password, Pull nor Push Correlation RuleConf");
112 throw sce;
113 }
114 break;
115
116 default:
117 Class<?> clazz = null;
118 try {
119 clazz = Class.forName(implementation.getBody());
120 } catch (Exception e) {
121 LOG.error("Class '{}' not found", implementation.getBody(), e);
122 sce.getElements().add("No Java class found: " + implementation.getBody());
123 throw sce;
124 }
125 if (!baseClazz.isAssignableFrom(clazz)) {
126 sce.getElements().add(
127 "Java class " + implementation.getBody() + " must comply with " + baseClazz.getName());
128 throw sce;
129 }
130 if (Modifier.isAbstract(clazz.getModifiers())) {
131 sce.getElements().add("Java class " + implementation.getBody() + " is abstract");
132 throw sce;
133 }
134 break;
135 }
136 }
137 }
138
139 @Override
140 public ImplementationTO getImplementationTO(final Implementation implementation) {
141 ImplementationTO implementationTO = new ImplementationTO();
142 implementationTO.setKey(implementation.getKey());
143 implementationTO.setEngine(implementation.getEngine());
144 implementationTO.setType(implementation.getType());
145 implementationTO.setBody(implementation.getBody());
146
147 return implementationTO;
148 }
149 }