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.plugins.repository.data.holder;
017
018import java.util.Map;
019import java.util.Optional;
020
021import org.ametys.plugins.repository.data.UnknownDataException;
022import org.ametys.plugins.repository.data.external.ExternalizableDataProvider.ExternalizableDataStatus;
023import org.ametys.plugins.repository.data.holder.group.ModifiableModelAwareComposite;
024import org.ametys.plugins.repository.data.holder.group.ModifiableRepeater;
025import org.ametys.plugins.repository.data.holder.values.SynchronizationContext;
026import org.ametys.plugins.repository.data.holder.values.SynchronizationResult;
027import org.ametys.runtime.model.ViewItemAccessor;
028import org.ametys.runtime.model.exception.BadDataPathCardinalityException;
029import org.ametys.runtime.model.exception.BadItemTypeException;
030import org.ametys.runtime.model.exception.NotUniqueTypeException;
031import org.ametys.runtime.model.exception.UndefinedItemPathException;
032import org.ametys.runtime.model.exception.UnknownTypeException;
033
034/**
035 * Interface for modifiable data containers with models
036 */
037public interface ModifiableModelAwareDataHolder extends ModifiableDataHolder, ModelAwareDataHolder
038{
039    @Override
040    public ModifiableModelAwareComposite getComposite(String compositePath) throws IllegalArgumentException, UnknownTypeException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
041    
042    @Override
043    public ModifiableModelAwareComposite getLocalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
044    
045    @Override
046    public ModifiableModelAwareComposite getExternalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
047    
048    @Override
049    public ModifiableRepeater getRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
050    
051    @Override
052    public ModifiableRepeater getLocalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
053    
054    @Override
055    public ModifiableRepeater getExternalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
056    
057    @Override
058    public ModifiableModelAwareComposite getComposite(String compositePath, boolean createNew) throws IllegalArgumentException, UnknownTypeException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
059    
060    /**
061     * Retrieves the local composite at the given path
062     * @param compositePath path of the externalizable composite to retrieve
063     * @param createNew <code>true</code> to create the composite if it does not exist, <code>false</code> otherwise
064     * @return the composite or <code>null</code> if createNew is <code>false</code> and value not exists or is empty
065     * @throws IllegalArgumentException if the given composite path is null or empty
066     * @throws BadItemTypeException if the stored value at the given path is not a composite
067     * @throws UndefinedItemPathException if the given composite path is not defined by the model
068     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
069     */
070    public ModifiableModelAwareComposite getLocalComposite(String compositePath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
071    
072    /**
073     * Retrieves the external composite at the given path
074     * @param compositePath path of the externalizable composite to retrieve
075     * @param createNew <code>true</code> to create the composite if it does not exist, <code>false</code> otherwise
076     * @return the composite or <code>null</code> if createNew is <code>false</code> and value not exists or is empty
077     * @throws IllegalArgumentException if the given composite path is null or empty
078     * @throws BadItemTypeException if the stored value at the given path is not a composite
079     * @throws UndefinedItemPathException if the given composite path is not defined by the model
080     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
081     */
082    public ModifiableModelAwareComposite getExternalComposite(String compositePath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
083    
084    /**
085     * Retrieves the repeater at the given path
086     * @param repeaterPath path of the repeater to retrieve
087     * @param createNew <code>true</code> to create the repeater if it does not exist, <code>false</code> otherwise
088     * @return the repeater or <code>null</code> if createNew is <code>false</code> and value not exists or is empty
089     * @throws IllegalArgumentException if the given repeater path is null or empty
090     * @throws BadItemTypeException if the stored value at the given path is not a repeater
091     * @throws UndefinedItemPathException if the given composite path is not defined by the model
092     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
093     */
094    public ModifiableRepeater getRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
095    
096    /**
097     * Retrieves the local repeater at the given path
098     * @param repeaterPath path of the externalizable repeater to retrieve
099     * @param createNew <code>true</code> to create the repeater if it does not exist, <code>false</code> otherwise
100     * @return the repeater or <code>null</code> if createNew is <code>false</code> and value not exists or is empty
101     * @throws IllegalArgumentException if the given repeater path is null or empty
102     * @throws BadItemTypeException if the stored value at the given path is not a repeater
103     * @throws UndefinedItemPathException if the given composite path is not defined by the model
104     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
105     */
106    public ModifiableRepeater getLocalRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
107    
108    /**
109     * Retrieves the external repeater at the given path
110     * @param repeaterPath path of the externalizable repeater to retrieve
111     * @param createNew <code>true</code> to create the repeater if it does not exist, <code>false</code> otherwise
112     * @return the repeater or <code>null</code> if createNew is <code>false</code> and value not exists or is empty
113     * @throws IllegalArgumentException if the given repeater path is null or empty
114     * @throws BadItemTypeException if the stored value at the given path is not a repeater
115     * @throws UndefinedItemPathException if the given composite path is not defined by the model
116     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
117     */
118    public ModifiableRepeater getExternalRepeater(String repeaterPath, boolean createNew) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
119    
120    /**
121     * Synchronizes the given values with the current ones
122     * @param <T> the type of the {@link SynchronizationResult}
123     * @param values the values to synchronize
124     * @param context the context of the synchronization
125     * @return the {@link SynchronizationResult}
126     * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value
127     * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model
128     */
129    public <T extends SynchronizationResult> T synchronizeValues(Map<String, Object> values, SynchronizationContext context) throws BadItemTypeException, UndefinedItemPathException;
130    
131    /**
132     * Synchronizes the given values with the current ones
133     * @param <T> the type of the {@link SynchronizationResult}
134     * @param viewItemAccessor The {@link ViewItemAccessor} for all items to synchronize
135     * @param values the values to synchronize
136     * @return the {@link SynchronizationResult}
137     * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value
138     * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model
139     */
140    public <T extends SynchronizationResult> T synchronizeValues(ViewItemAccessor viewItemAccessor, Map<String, Object> values) throws BadItemTypeException, UndefinedItemPathException;
141    
142    /**
143     * Synchronizes the given values with the current {@link ModifiableModelAwareDataHolder}'s ones
144     * @param <T> the type of the {@link SynchronizationResult}
145     * @param viewItemAccessor The {@link ViewItemAccessor} for all items to synchronize
146     * @param values the values to synchronize
147     * @param context the context of the synchronization
148     * @return the {@link SynchronizationResult}
149     * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value
150     * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model
151     */
152    public <T extends SynchronizationResult> T synchronizeValues(ViewItemAccessor viewItemAccessor, Map<String, Object> values, SynchronizationContext context) throws BadItemTypeException, UndefinedItemPathException;
153    
154    /**
155     * {@inheritDoc}
156     * @param value the value to set. Give <code>null</code> to empty the value.
157     */
158    public void setValue(String dataPath, Object value) throws IllegalArgumentException, UnknownDataException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
159    
160    /**
161     * Sets the local value of the data at the given path
162     * @param dataPath path of the externalizable data
163     * @param localValue the local value to set. Give <code>null</code> to empty the value.
164     * @throws IllegalArgumentException if the given data path is null or empty
165     * @throws BadItemTypeException if the type defined by the model doesn't match the given value to set
166     * @throws UndefinedItemPathException if the given data path is not defined by the model
167     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
168     */
169    public void setLocalValue(String dataPath, Object localValue) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
170    
171    /**
172     * Sets the external value of the data at the given path
173     * @param dataPath path of the externalizable data
174     * @param externalValue the external value to set. Give <code>null</code> to empty the value.
175     * @throws IllegalArgumentException if the given data path is null or empty
176     * @throws BadItemTypeException if the type defined by the model doesn't match the given value to set
177     * @throws UndefinedItemPathException if the given data path is not defined by the model
178     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
179     */
180    public void setExternalValue(String dataPath, Object externalValue) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
181
182    /**
183     * Set the status of the data at the given path
184     * @param dataPath path of the externalizable data
185     * @param status the new status
186     * @throws IllegalArgumentException if the given data path is null or empty
187     * @throws BadItemTypeException if there is a type issue while getting the parent (part of the dataPath without the last segment)
188     * @throws UndefinedItemPathException if the given data path is not defined by the model
189     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
190     */
191    public void setStatus(String dataPath, ExternalizableDataStatus status) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
192    
193    /**
194     * {@inheritDoc}
195     * @throws BadItemTypeException if the type defined by the model doesn't match the given value to set
196     */
197    @Override
198    public default void setValue(String dataPath, Object value, String dataTypeId) throws IllegalArgumentException, UnknownDataException, UnknownTypeException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException
199    {
200        setValue(dataPath, value);
201    }
202    
203    /**
204     * Removes the local value of the data at the given path
205     * @param dataPath path of the externalizable data
206     * @throws IllegalArgumentException if the given data path is null or empty
207     * @throws BadItemTypeException if the value of the parent of the given path is not an item container
208     * @throws UndefinedItemPathException if the given data path is not defined by the model
209     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
210     */
211    public void removeLocalValue(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
212    
213    /**
214     * Removes the external value of the data at the given path
215     * @param dataPath path of the externalizable data
216     * @throws IllegalArgumentException if the given data path is null or empty
217     * @throws BadItemTypeException if the value of the parent of the given path is not an item container
218     * @throws UndefinedItemPathException if the given data path is not defined by the model
219     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
220     */
221    public void removeExternalValue(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
222    
223    /**
224     * Removes the stored metadata (status and alternative value) for externalizable (or ex-externalizable) data
225     * @param dataPath path of the data
226     * @throws IllegalArgumentException if the given data path is null or empty
227     * @throws BadItemTypeException if the value of the parent of the given path is not an item container
228     * @throws UndefinedItemPathException if the given data path is not defined by the model
229     * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple
230     */
231    public void removeExternalizableMetadataIfExists(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException;
232    
233    @Override
234    public Optional<? extends ModifiableModelAwareDataHolder> getParentDataHolder();
235    
236    @Override
237    public ModifiableModelAwareDataHolder getRootDataHolder();
238}