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.holder.group.impl;
017
018import java.util.Optional;
019
020import org.ametys.cms.data.holder.ModifiableIndexableDataHolder;
021import org.ametys.cms.data.holder.group.ModifiableIndexableRepeater;
022import org.ametys.cms.data.holder.group.ModifiableIndexableRepeaterEntry;
023import org.ametys.cms.data.holder.impl.DefaultModifiableModelAwareDataHolder;
024import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData;
025import org.ametys.plugins.repository.lock.LockableAmetysObject;
026import org.ametys.plugins.repository.model.RepeaterDefinition;
027
028/**
029 * Class for modifiable model aware repeater entries
030 */
031public class DefaultModifiableModelAwareRepeaterEntry extends DefaultModelAwareRepeaterEntry implements ModifiableIndexableRepeaterEntry
032{
033    /** The modifiable repository data if the repeater entry is modifiable */
034    protected ModifiableRepositoryData _modifiableRepositoryData;
035    
036    /** Ametys object that can be locked on data modification */
037    protected Optional<LockableAmetysObject> _lockableAmetysObject;
038    
039    /** the repeater containing this entry */
040    protected ModifiableIndexableRepeater _modifiableRepeater;
041    
042    /** the default implementation of a {@link ModifiableIndexableDataHolder} to use */
043    protected ModifiableIndexableDataHolder _modifiableDefaultDataHolder;
044    
045    /**
046     * Creates a modifiable model aware repeater entry
047     * @param repositoryData the repository data of the repeater entry
048     * @param definition the definition of the repeater
049     * @param lockableAmetysObject the ametys object that can be locked on data modification
050     * @param repeater the repeater containing this entry
051     */
052    public DefaultModifiableModelAwareRepeaterEntry(ModifiableRepositoryData repositoryData, RepeaterDefinition definition, Optional<LockableAmetysObject> lockableAmetysObject, ModifiableIndexableRepeater repeater)
053    {
054        super(repositoryData, definition, repeater);
055        _modifiableDefaultDataHolder = new DefaultModifiableModelAwareDataHolder(repositoryData, definition, lockableAmetysObject, Optional.of(repeater.getParentDataHolder()), Optional.of(repeater.getRootDataHolder()));
056        _modifiableRepositoryData = repositoryData;
057        _lockableAmetysObject = lockableAmetysObject;
058        _modifiableRepeater = repeater;
059    }
060    
061    public void setPosition(int position) throws IllegalArgumentException
062    {
063        if (1 <= position && position <= _modifiableRepeater.getSize())
064        {
065            if (position != getPosition())
066            {
067                int oldPosition = getPosition();
068                _rename(String.valueOf(position) + "_tmp");
069                
070                // rename entries between the old and new position
071                if (position > oldPosition)
072                {
073                    for (int currentEntryPosition = oldPosition + 1; currentEntryPosition <= position; currentEntryPosition++)
074                    {
075                        DefaultModifiableModelAwareRepeaterEntry entry = (DefaultModifiableModelAwareRepeaterEntry) _modifiableRepeater.getEntry(currentEntryPosition);
076                        entry._rename(String.valueOf(currentEntryPosition - 1));
077                    }
078                }
079                else if (position < oldPosition)
080                {
081                    for (int currentEntryPosition = oldPosition - 1; currentEntryPosition >= position; currentEntryPosition--)
082                    {
083                        DefaultModifiableModelAwareRepeaterEntry entry = (DefaultModifiableModelAwareRepeaterEntry) _modifiableRepeater.getEntry(currentEntryPosition);
084                        entry._rename(String.valueOf(currentEntryPosition + 1));
085                    }
086                }
087                
088                _rename(String.valueOf(position));
089            }
090        
091        }
092        else if (-_modifiableRepeater.getSize() < position && position <= 0)
093        {
094            // Find the positive equivalent position and call the setPosition method with this position
095            setPosition(_modifiableRepeater.getSize() + position);
096        }
097        else
098        {
099            throw new IllegalArgumentException("The repeater named '" + _modifiableRepositoryData.getName() + "' has '" + _modifiableRepeater.getSize() + "' entries. You can not set an entry at position '" + position + "'.");
100        }
101    }
102    
103    private void _rename(String newName)
104    {
105        _lockableAmetysObject.ifPresent(lao -> lao.setLockInfoOnCurrentContext());
106        _modifiableRepositoryData.rename(newName);
107    }
108    
109    @Override
110    public ModifiableIndexableDataHolder getDefaultDataHolder()
111    {
112        return _modifiableDefaultDataHolder;
113    }
114    
115    @Override
116    public ModifiableRepositoryData getRepositoryData()
117    {
118        return _modifiableRepositoryData;
119    }
120
121    @Override
122    public ModifiableIndexableRepeater getHoldingRepeater()
123    {
124        return _modifiableRepeater;
125    }
126}