001/*
002 *  Copyright 2022 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.forms.repository.type;
017
018import java.util.Arrays;
019import java.util.List;
020import java.util.Optional;
021import java.util.stream.Stream;
022
023import org.apache.commons.lang3.StringUtils;
024
025import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData;
026import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
027import org.ametys.plugins.repository.data.type.RepositoryElementType;
028import org.ametys.runtime.model.exception.BadItemTypeException;
029
030/**
031 * Class for rule element types
032 */
033public class RuleRepositoryElementType extends AbstractRuleElementType implements RepositoryElementType<Rule>
034{
035    public String getRepositoryDataType()
036    {
037        return RepositoryData.STRING_REPOSITORY_DATA_TYPE;
038    }
039
040    public Object read(RepositoryData parentData, String name) throws BadItemTypeException
041    {
042        if (!parentData.hasValue(name))
043        {
044            return null;
045        }
046        
047        if (!isCompatible(parentData, name))
048        {
049            throw new BadItemTypeException("Try to get " + getId() + " value from the non " + getId() + " data '" + name + "' on '" + parentData + "'");
050        }
051        
052        if (parentData.isMultiple(name))
053        {
054            String[] values = parentData.getStrings(name);
055            return Arrays.stream(values)
056                        .map(this::_string2Rule)
057                        .toArray(Rule[]::new);
058        }
059        else
060        {
061            String value = parentData.getString(name);
062            return _string2Rule(value);
063        }
064    }
065    
066    public boolean hasNonEmptyValue(RepositoryData parentData, String name) throws BadItemTypeException
067    {
068        if (!parentData.hasValue(name))
069        {
070            return false;
071        }
072        
073        if (!isCompatible(parentData, name))
074        {
075            throw new BadItemTypeException("Try to check rule value from the non " + getId() + " data '" + name + "' on '" + parentData + "'");
076        }
077        
078        if (parentData.isMultiple(name))
079        {
080            return parentData.getStrings(name).length > 0;
081        }
082        else
083        {
084            return StringUtils.isNotEmpty(parentData.getString(name));
085        }
086    }
087
088    public void write(ModifiableRepositoryData parentData, String name, Object value) throws BadItemTypeException
089    {
090        if (value == null)
091        {
092            if (parentData.hasValue(name) && parentData.isMultiple(name))
093            {
094                parentData.setValues(name, new String[0]);
095            }
096            else
097            {
098                parentData.setValue(name, StringUtils.EMPTY);
099            }
100        }
101        else if (value instanceof String)
102        {
103            parentData.setValue(name, (String) value);
104        }
105        else if (value instanceof String[])
106        {
107            Arrays.stream((String[]) value)
108                  .forEach(v -> Optional.ofNullable(v)
109                                        .orElseThrow(() -> new IllegalArgumentException("Try to set a null value into the multiple " + getId() + " data '" + name + "' on '" + parentData + "'")));
110            
111            parentData.setValues(name, (String[]) value);
112        }
113        else if (value instanceof Rule)
114        {
115            Rule rule = (Rule) value;
116            parentData.setValue(name, _jsonUtils.convertObjectToJson(rule.toJson()));
117        }
118        else if (value instanceof Rule[])
119        {
120            String[] values = Stream.of((Rule[]) value)
121                .map(r -> _jsonUtils.convertObjectToJson(r.toJson()))
122                .toArray(String[]::new);
123            
124            parentData.setValues(name, values);
125        }
126        else if (value instanceof List)
127        {
128            @SuppressWarnings("unchecked")
129            List<Rule> ruleList = (List<Rule>) value;
130            String[] ruleListAsJson = ruleList.stream()
131                .map(r -> _jsonUtils.convertObjectToJson(r.toJson()))
132                .toArray(String[]::new);
133            
134            parentData.setValues(name, ruleListAsJson);
135        }
136        else
137        {
138            throw new BadItemTypeException("Try to set the non " + getId() + " value '" + value + "' to the " + getId() + " data '" + name + "' on '" + parentData + "'");
139        }
140    }
141}