/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.syncope.core.provisioning.java.data; import java.util.ArrayList; import org.apache.syncope.core.provisioning.api.data.ConfigurationDataBinder; import java.util.Collections; import java.util.List; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.MapContext; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.core.provisioning.java.jexl.JexlUtils; import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; import org.apache.syncope.core.persistence.api.dao.ConfDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue; import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ConfigurationDataBinderImpl extends AbstractAnyDataBinder implements ConfigurationDataBinder { @Autowired private ConfDAO confDAO; @Override public List<AttrTO> getConfTO() { List<AttrTO> attrTOs = new ArrayList<>(); for (CPlainAttr attr : confDAO.get().getPlainAttrs()) { attrTOs.add(getAttrTO(attr)); } return attrTOs; } @Override public AttrTO getAttrTO(final CPlainAttr attr) { return new AttrTO.Builder(). schemaInfo(schemaDataBinder.getPlainSchemaTO(attr.getSchema())). schema(attr.getSchema().getKey()). values(attr.getValuesAsStrings()). build(); } private void fillAttr(final List<String> values, final PlainSchema schema, final CPlainAttr attr, final SyncopeClientException invalidValues) { // if schema is multivalue, all values are considered for addition; // otherwise only the fist one - if provided - is considered List<String> valuesProvided = schema.isMultivalue() ? values : (values.isEmpty() ? Collections.<String>emptyList() : Collections.singletonList(values.iterator().next())); if (valuesProvided.isEmpty()) { JexlContext jexlContext = new MapContext(); JexlUtils.addPlainAttrsToContext(confDAO.get().getPlainAttrs(), jexlContext); if (!schema.isReadonly() && Boolean.parseBoolean(JexlUtils.evaluate(schema.getMandatoryCondition(), jexlContext))) { LOG.error("Mandatory schema " + schema.getKey() + " not provided with values"); SyncopeClientException reqValMissing = SyncopeClientException.build( ClientExceptionType.RequiredValuesMissing); reqValMissing.getElements().add(schema.getKey()); throw reqValMissing; } } for (String value : valuesProvided) { if (value == null || value.isEmpty()) { LOG.debug("Null value for {}, ignoring", schema.getKey()); } else { try { PlainAttrValue attrValue; if (schema.isUniqueConstraint()) { attrValue = entityFactory.newEntity(CPlainAttrUniqueValue.class); ((PlainAttrUniqueValue) attrValue).setSchema(schema); } else { attrValue = entityFactory.newEntity(CPlainAttrValue.class); } attr.add(value, attrValue); } catch (InvalidPlainAttrValueException e) { LOG.warn("Invalid value for attribute " + schema.getKey() + ": " + value, e); invalidValues.getElements().add(schema.getKey() + ": " + value + " - " + e.getMessage()); } } } } @Override public CPlainAttr getAttr(final AttrTO attrTO) { PlainSchema schema = getPlainSchema(attrTO.getSchema()); if (schema == null) { throw new NotFoundException("Conf schema " + attrTO.getSchema()); } else { SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues); CPlainAttr attr = entityFactory.newEntity(CPlainAttr.class); attr.setSchema(schema); fillAttr(attrTO.getValues(), schema, attr, invalidValues); if (!invalidValues.isEmpty()) { throw invalidValues; } return attr; } } }