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