001/*
002 *  Copyright 2019 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.ametysobject;
017
018import java.util.Collection;
019import java.util.List;
020import java.util.Map;
021import java.util.Optional;
022
023import org.xml.sax.ContentHandler;
024import org.xml.sax.SAXException;
025
026import org.ametys.plugins.repository.AmetysObject;
027import org.ametys.plugins.repository.data.DataComment;
028import org.ametys.plugins.repository.data.external.ExternalizableDataProvider.ExternalizableDataStatus;
029import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
030import org.ametys.plugins.repository.data.holder.group.ModelAwareComposite;
031import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeater;
032import org.ametys.plugins.repository.data.holder.impl.DataHolderHelper;
033import org.ametys.plugins.repository.data.holder.values.SynchronizationContext;
034import org.ametys.runtime.model.Model;
035import org.ametys.runtime.model.ModelItem;
036import org.ametys.runtime.model.ViewItemAccessor;
037import org.ametys.runtime.model.ViewItemContainer;
038import org.ametys.runtime.model.exception.BadDataPathCardinalityException;
039import org.ametys.runtime.model.exception.BadItemTypeException;
040import org.ametys.runtime.model.exception.UndefinedItemPathException;
041import org.ametys.runtime.model.type.DataContext;
042
043/**
044 * Model aware {@link AmetysObject} that can handle data.
045 */
046public interface ModelAwareDataAwareAmetysObject extends DataAwareAmetysObject, ModelAwareDataHolder
047{
048    @Override
049    public ModelAwareDataHolder getDataHolder();
050    
051    public default ModelAwareComposite getComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
052    {
053        return getDataHolder().getComposite(compositePath);
054    }
055    
056    public default ModelAwareComposite getLocalComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
057    {
058        return getDataHolder().getLocalComposite(compositePath);
059    }
060    
061    public default ModelAwareComposite getExternalComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
062    {
063        return getDataHolder().getExternalComposite(compositePath);
064    }
065
066    public default ModelAwareRepeater getRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
067    {
068        return getDataHolder().getRepeater(repeaterPath);
069    }
070
071    public default ModelAwareRepeater getLocalRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
072    {
073        return getDataHolder().getLocalRepeater(repeaterPath);
074    }
075
076    public default ModelAwareRepeater getExternalRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
077    {
078        return getDataHolder().getExternalRepeater(repeaterPath);
079    }
080    
081    public default boolean hasValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
082    {
083        return DataAwareAmetysObject.super.hasValue(dataPath);
084    }
085    
086    public default boolean hasLocalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
087    {
088        return getDataHolder().hasLocalValue(dataPath);
089    }
090    
091    public default boolean hasExternalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
092    {
093        return getDataHolder().hasExternalValue(dataPath);
094    }
095    
096    public default boolean hasValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
097    {
098        return DataAwareAmetysObject.super.hasValueOrEmpty(dataPath);
099    }
100    
101    public default boolean hasLocalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
102    {
103        return getDataHolder().hasLocalValueOrEmpty(dataPath);
104    }
105    
106    public default boolean hasExternalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException
107    {
108        return getDataHolder().hasExternalValueOrEmpty(dataPath);
109    }
110    
111    default boolean hasComments(String dataName) throws IllegalArgumentException, UndefinedItemPathException
112    {
113        return getDataHolder().hasComments(dataName);
114    }
115
116    public default <T extends Object> T getValue(String dataPath, boolean allowMultiValuedPathSegments) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
117    {
118        return getDataHolder().getValue(dataPath, allowMultiValuedPathSegments);
119    }
120    
121    public default <T> T getValue(String dataPath, boolean useDefaultFromModel, T defaultValue) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
122    {
123        return getDataHolder().getValue(dataPath, useDefaultFromModel, defaultValue);
124    }
125    
126    public default <T> T getLocalValue(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
127    {
128        return getDataHolder().getLocalValue(dataPath);
129    }
130    
131    public default <T> T getExternalValue(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException
132    {
133        return getDataHolder().getExternalValue(dataPath);
134    }
135    
136    public default ExternalizableDataStatus getStatus(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadDataPathCardinalityException
137    {
138        return getDataHolder().getStatus(dataPath);
139    }
140    
141    default List<DataComment> getComments(String dataName) throws IllegalArgumentException, UndefinedItemPathException
142    {
143        return getDataHolder().getComments(dataName);
144    }
145    
146    @SuppressWarnings("unchecked")
147    public default Collection<? extends Model> getModel()
148    {
149        return (Collection<? extends Model>) getDataHolder().getModel();
150    }
151    
152    public default ModelItem getDefinition(String path) throws IllegalArgumentException, UndefinedItemPathException
153    {
154        return getDataHolder().getDefinition(path);
155    }
156    
157    default boolean hasDefinition(String path) throws IllegalArgumentException
158    {
159        return getDataHolder().hasDefinition(path);
160    }
161    
162    public default Collection<String> getDataNames()
163    {
164        return getDataHolder().getDataNames();
165    }
166    
167    public default void dataToSAX(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException
168    {
169        getDataHolder().dataToSAX(contentHandler, viewItemAccessor, context);
170    }
171    
172    public default void dataToSAXForEdition(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException
173    {
174        getDataHolder().dataToSAXForEdition(contentHandler, viewItemAccessor, context);
175    }
176    
177    public default Map<String, Object> dataToJSON(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException
178    {
179        return getDataHolder().dataToJSON(viewItemAccessor, context);
180    }
181    
182    public default Map<String, Object> dataToJSONForEdition(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException
183    {
184        return getDataHolder().dataToJSONForEdition(viewItemAccessor, context);
185    }
186    
187    public default Map<String, Object> dataToMap(ViewItemAccessor viewItemAccessor, DataContext context)
188    {
189        return getDataHolder().dataToMap(viewItemAccessor, context);
190    }
191    
192    /**
193     * Check if there are differences between the given values and the current ones
194     * @param values the values to check
195     * @param context the context of the synchronization
196     * @return <code>true</code> if there are differences, <code>false</code> otherwise
197     * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model
198     * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value
199     */
200    public default boolean hasDifferences(Map<String, Object> values, SynchronizationContext context) throws UndefinedItemPathException, BadItemTypeException
201    {
202        ViewItemContainer viewItemContainer = DataHolderHelper.createViewItemContainerFromValues(getModel(), values);
203        return hasDifferences(viewItemContainer, values, context);
204    }
205    
206    public default boolean hasDifferences(ViewItemContainer viewItemContainer, Map<String, Object> values, SynchronizationContext context) throws UndefinedItemPathException, BadItemTypeException
207    {
208        Map<String, Object> convertedValues = DataHolderHelper.convertValues(viewItemContainer, values, DataHolderHelper::convertValueIgnoringIncompatibleOnes);
209        return getDataHolder().hasDifferences(viewItemContainer, convertedValues, context);
210    }
211    
212    public default Optional<? extends ModelAwareDataHolder> getParentDataHolder()
213    {
214        return getDataHolder().getParentDataHolder();
215    }
216    
217    public default ModelAwareDataHolder getRootDataHolder()
218    {
219        return getDataHolder().getRootDataHolder();
220    }
221}