001/*
002 *  Copyright 2018 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.cms.data.type.impl;
017
018import java.util.Arrays;
019import java.util.Optional;
020
021import org.apache.commons.lang3.ArrayUtils;
022
023import org.ametys.core.model.type.AbstractLongElementType;
024import org.ametys.plugins.repository.RepositoryConstants;
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 long type of elements stored in the repository
032 */
033public class LongRepositoryElementType extends AbstractLongElementType implements RepositoryElementType<Long>
034{
035    public Object read(RepositoryData parentData, String name) throws BadItemTypeException
036    {
037        if (!parentData.hasValue(name))
038        {
039            return null;
040        }
041        
042        if (!isCompatible(parentData, name))
043        {
044            throw new BadItemTypeException("Try to get long value from the non long data '" + name + "' on '" + parentData + "'");
045        }
046        
047        if (parentData.isMultiple(name))
048        {
049            return parentData.getLongs(name);
050        }
051        else
052        {
053            return parentData.getLong(name);
054        }
055    }
056    
057    @Override
058    public boolean hasValue(RepositoryData parentData, String name) throws BadItemTypeException
059    {
060        return RepositoryElementType.super.hasValue(parentData, name) || parentData.hasValue(name + EMPTY_METADATA_SUFFIX, RepositoryConstants.NAMESPACE_PREFIX_INTERNAL);
061    }
062    
063    public boolean hasNonEmptyValue(RepositoryData parentData, String name) throws BadItemTypeException
064    {
065        if (!parentData.hasValue(name))
066        {
067            return false;
068        }
069        
070        if (!isCompatible(parentData, name))
071        {
072            throw new BadItemTypeException("Try to check long value from the non long data '" + name + "' on '" + parentData + "'");
073        }
074        
075        if (parentData.isMultiple(name))
076        {
077            return parentData.getLongs(name).length > 0;
078        }
079        else
080        {
081            return true;
082        }
083    }
084
085    public void write(ModifiableRepositoryData parentData, String name, Object value) throws BadItemTypeException
086    {
087        if (value == null)
088        {
089            if (parentData.hasValue(name) && parentData.isMultiple(name))
090            {
091                parentData.setValues(name, new Long[0]);
092            }
093            else
094            {
095                parentData.setValue(name + EMPTY_METADATA_SUFFIX, true, RepositoryConstants.NAMESPACE_PREFIX_INTERNAL);
096
097                if (parentData.hasValue(name))
098                {
099                    parentData.removeValue(name);
100                }
101            }
102        }
103        else if (value instanceof Number)
104        {
105            parentData.setValue(name, ((Number) value).longValue());
106            
107            if (parentData.hasValue(name + EMPTY_METADATA_SUFFIX, RepositoryConstants.NAMESPACE_PREFIX_INTERNAL))
108            {
109                parentData.removeValue(name + EMPTY_METADATA_SUFFIX, RepositoryConstants.NAMESPACE_PREFIX_INTERNAL);
110            }
111        }
112        else if (value instanceof long[])
113        {
114            parentData.setValues(name, ArrayUtils.toObject((long[]) value));
115        }
116        else if (value instanceof int[])
117        {
118            Long[] valueAsLongArray = Arrays.stream(ArrayUtils.toObject((int[]) value))
119                    .map(intValue -> intValue.longValue())
120                    .toArray(Long[]::new);
121
122            parentData.setValues(name, valueAsLongArray);
123        }
124        else if (value instanceof Number[])
125        {
126            Long[] valueAsLongArray = Arrays.stream((Number[]) value)
127                                            .map(v -> Optional.ofNullable(v)
128                                                              .orElseThrow(() -> new IllegalArgumentException("Try to set a null value into the multiple " + getId() + " data '" + name + "' on '" + parentData + "'")))
129                                            .map(number -> number.longValue())
130                                            .toArray(Long[]::new);
131            
132            parentData.setValues(name, valueAsLongArray);
133        }
134        else
135        {
136            throw new BadItemTypeException("Try to set the non long value '" + value + "' to the long data '" + name + "' on '" + parentData + "'");
137        }
138    }
139    
140    public String getRepositoryDataType()
141    {
142        return RepositoryData.LONG_REPOSITORY_DATA_TYPE;
143    }
144}