blob: 47b393ec8261d67546d12ded202d24cf1fc72faf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.core.logic;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.request.AnyCR;
import org.apache.syncope.common.lib.request.AnyObjectCR;
import org.apache.syncope.common.lib.request.AnyUR;
import org.apache.syncope.common.lib.request.GroupCR;
import org.apache.syncope.common.lib.request.UserCR;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.dao.RealmDAO;
import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
import org.apache.syncope.core.persistence.api.entity.AnyType;
import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.LogicActions;
import org.apache.syncope.core.spring.ImplementationManager;
public abstract class AbstractAnyLogic<TO extends AnyTO, C extends AnyCR, U extends AnyUR>
extends AbstractResourceAssociator<TO> {
protected static final String REST_CONTEXT = "REST";
protected final RealmDAO realmDAO;
protected final AnyTypeDAO anyTypeDAO;
protected final TemplateUtils templateUtils;
public AbstractAnyLogic(
final RealmDAO realmDAO,
final AnyTypeDAO anyTypeDAO,
final TemplateUtils templateUtils) {
this.realmDAO = realmDAO;
this.anyTypeDAO = anyTypeDAO;
this.templateUtils = templateUtils;
}
protected List<LogicActions> getActions(final Realm realm) {
List<LogicActions> actions = new ArrayList<>();
realm.getActions().forEach(impl -> {
try {
actions.add(ImplementationManager.build(impl));
} catch (Exception e) {
LOG.warn("While building {}", impl, e);
}
});
return actions;
}
@SuppressWarnings("unchecked")
protected Pair<C, List<LogicActions>> beforeCreate(final C input) {
Realm realm = realmDAO.findByFullPath(input.getRealm());
if (realm == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
sce.getElements().add(input.getRealm());
throw sce;
}
AnyType anyType = null;
if (input instanceof UserCR) {
anyType = anyTypeDAO.findUser();
} else if (input instanceof GroupCR) {
anyType = anyTypeDAO.findGroup();
} else if (input instanceof AnyObjectCR) {
anyType = anyTypeDAO.find(((AnyObjectCR) input).getType());
}
if (anyType == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
throw sce;
}
C anyCR = input;
templateUtils.apply(anyCR, realm.getTemplate(anyType));
List<LogicActions> actions = getActions(realm);
for (LogicActions action : actions) {
anyCR = action.beforeCreate(anyCR);
}
LOG.debug("Input: {}\nOutput: {}\n", input, anyCR);
return Pair.of(anyCR, actions);
}
@SuppressWarnings("unchecked")
protected Pair<U, List<LogicActions>> beforeUpdate(final U input, final String realmPath) {
Realm realm = realmDAO.findByFullPath(realmPath);
if (realm == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
sce.getElements().add(realmPath);
throw sce;
}
U update = input;
List<LogicActions> actions = getActions(realm);
for (LogicActions action : actions) {
update = action.beforeUpdate(update);
}
LOG.debug("Input: {}\nOutput: {}\n", input, update);
return Pair.of(update, actions);
}
@SuppressWarnings("unchecked")
protected Pair<TO, List<LogicActions>> beforeDelete(final TO input) {
Realm realm = realmDAO.findByFullPath(input.getRealm());
if (realm == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
sce.getElements().add(input.getRealm());
throw sce;
}
TO any = input;
List<LogicActions> actions = getActions(realm);
for (LogicActions action : actions) {
any = action.beforeDelete(any);
}
LOG.debug("Input: {}\nOutput: {}\n", input, any);
return Pair.of(any, actions);
}
@SuppressWarnings("unchecked")
protected ProvisioningResult<TO> afterCreate(
final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
TO any = input;
for (LogicActions action : actions) {
any = action.afterCreate(any, statuses);
}
ProvisioningResult<TO> result = new ProvisioningResult<>();
result.setEntity(any);
result.getPropagationStatuses().addAll(statuses);
return result;
}
protected ProvisioningResult<TO> afterUpdate(
final TO input,
final List<PropagationStatus> statuses,
final List<LogicActions> actions) {
TO any = input;
for (LogicActions action : actions) {
any = action.afterUpdate(any, statuses);
}
ProvisioningResult<TO> result = new ProvisioningResult<>();
result.setEntity(any);
result.getPropagationStatuses().addAll(statuses);
return result;
}
@SuppressWarnings("unchecked")
protected ProvisioningResult<TO> afterDelete(
final TO input, final List<PropagationStatus> statuses, final List<LogicActions> actions) {
TO any = input;
for (LogicActions action : actions) {
any = action.afterDelete(any, statuses);
}
ProvisioningResult<TO> result = new ProvisioningResult<>();
result.setEntity(any);
result.getPropagationStatuses().addAll(statuses);
return result;
}
public abstract TO read(String key);
public abstract Pair<Integer, List<TO>> search(
SearchCond searchCond,
int page, int size, List<OrderByClause> orderBy,
String realm,
boolean details);
public abstract ProvisioningResult<TO> update(U updateReq, boolean nullPriorityAsync);
public abstract ProvisioningResult<TO> delete(String key, boolean nullPriorityAsync);
}