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.Collection; 019import java.util.List; 020import java.util.Map; 021import java.util.Optional; 022 023import org.apache.commons.lang3.StringUtils; 024import org.xml.sax.ContentHandler; 025import org.xml.sax.SAXException; 026 027import org.ametys.plugins.repository.data.DataComment; 028import org.ametys.plugins.repository.data.external.ExternalizableDataProvider.ExternalizableDataStatus; 029import org.ametys.plugins.repository.data.holder.group.ModelAwareComposite; 030import org.ametys.plugins.repository.data.holder.group.ModelAwareRepeater; 031import org.ametys.plugins.repository.data.holder.impl.DataHolderHelper; 032import org.ametys.plugins.repository.data.holder.values.SynchronizationContext; 033import org.ametys.plugins.repository.model.RepeaterDefinition; 034import org.ametys.runtime.model.ElementDefinition; 035import org.ametys.runtime.model.ModelHelper; 036import org.ametys.runtime.model.ModelItem; 037import org.ametys.runtime.model.ModelItemContainer; 038import org.ametys.runtime.model.ViewHelper; 039import org.ametys.runtime.model.ViewItemAccessor; 040import org.ametys.runtime.model.exception.BadDataPathCardinalityException; 041import org.ametys.runtime.model.exception.BadItemTypeException; 042import org.ametys.runtime.model.exception.UndefinedItemPathException; 043import org.ametys.runtime.model.type.DataContext; 044import org.ametys.runtime.model.type.ModelItemType; 045 046/** 047 * Interface for data containers with models 048 */ 049public interface ModelAwareDataHolder extends DataHolder 050{ 051 /** Suffix used for the alternative value */ 052 public static final String ALTERNATIVE_SUFFIX = "__alt"; 053 /** Suffix used for the status value */ 054 public static final String STATUS_SUFFIX = "__status"; 055 /** Suffix used for the comments */ 056 public static final String COMMENTS_SUFFIX = "_comments"; 057 058 /** 059 * {@inheritDoc} 060 * @throws UndefinedItemPathException if the given composite path is not defined by the model 061 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 062 */ 063 public ModelAwareComposite getComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 064 065 /** 066 * Retrieves the local composite at the given path 067 * @param compositePath path of the externalizable composite to retrieve 068 * @return the composite or <code>null</code> if not exists or is empty 069 * @throws IllegalArgumentException if the given composite path is null or empty 070 * @throws BadItemTypeException if the stored value at the given path is not a composite 071 * @throws UndefinedItemPathException if the given composite path is not defined by the model 072 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 073 */ 074 public ModelAwareComposite getLocalComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 075 076 /** 077 * Retrieves the external composite at the given path 078 * @param compositePath path of the externalizable composite to retrieve 079 * @return the composite or <code>null</code> if not exists or is empty 080 * @throws IllegalArgumentException if the given composite path is null or empty 081 * @throws BadItemTypeException if the stored value at the given path is not a composite 082 * @throws UndefinedItemPathException if the given composite path is not defined by the model 083 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 084 */ 085 public ModelAwareComposite getExternalComposite(String compositePath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 086 087 /** 088 * Retrieves the repeater at the given path 089 * @param repeaterPath path of the repeater to retrieve 090 * @return the repeater or <code>null</code> if not exists or is empty 091 * @throws IllegalArgumentException if the given repeater path is null or empty 092 * @throws BadItemTypeException if the stored value at the given path is not a repeater 093 * @throws UndefinedItemPathException if the given repeater path is not defined by the model 094 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 095 */ 096 public ModelAwareRepeater getRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 097 098 /** 099 * Retrieves the local repeater at the given path 100 * @param repeaterPath path of the externalizable repeater to retrieve 101 * @return the repeater or <code>null</code> if not exists or is empty 102 * @throws IllegalArgumentException if the given repeater path is null or empty 103 * @throws BadItemTypeException if the stored value at the given path is not a repeater 104 * @throws UndefinedItemPathException if the given repeater path is not defined by the model 105 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 106 */ 107 public ModelAwareRepeater getLocalRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 108 109 /** 110 * Retrieves the external repeater at the given path 111 * @param repeaterPath path of the externalizable repeater to retrieve 112 * @return the repeater or <code>null</code> if 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 repeater 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 ModelAwareRepeater getExternalRepeater(String repeaterPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 119 120 /** 121 * {@inheritDoc} 122 * @return <code>true</code> if the data at the given path is defined by the model, if there is a non empty value for the data and if the type of this value matches the type of the definition. <code>false</code> otherwise 123 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 124 */ 125 @Override 126 public boolean hasValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 127 128 /** 129 * Checks if there is a non empty local value for the data at the given path 130 * @param dataPath path of the externalizable data 131 * @return <code>true</code> if the data at the given path is defined by the model, if there is a non empty local value for the data and if the type of this value matches the type of the definition. <code>false</code> otherwise 132 * @throws IllegalArgumentException if the given data path is null or empty 133 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 134 */ 135 public boolean hasLocalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 136 137 /** 138 * Checks if there is a non empty external value for the data at the given path 139 * @param dataPath path of the externalizable data 140 * @return <code>true</code> if the data at the given path is defined by the model, if there is a non empty external value for the data and if the type of this value matches the type of the definition. <code>false</code> otherwise 141 * @throws IllegalArgumentException if the given data path is null or empty 142 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 143 */ 144 public boolean hasExternalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 145 146 /** 147 * {@inheritDoc} 148 * @return <code>true</code> if the data at the given path is defined by the model, if there is a value for the data, even empty, and if the type of this value matches the type of the definition. <code>false</code> otherwise 149 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 150 */ 151 @Override 152 public boolean hasValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 153 154 /** 155 * Checks if there is a local value for the data at the given path 156 * @param dataPath path of the externalizable data 157 * @return <code>true</code> if the data at the given path is defined by the model, if there is a local value for the data, even empty, and if the type of this value matches the type of the definition. <code>false</code> otherwise 158 * @throws IllegalArgumentException if the given data path is null or empty 159 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 160 */ 161 public boolean hasLocalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 162 163 /** 164 * Checks if there is an external value for the data at the given path 165 * @param dataPath path of the externalizable data 166 * @return <code>true</code> if the data at the given path is defined by the model, if there is an external value for the data, even empty, and if the type of this value matches the type of the definition. <code>false</code> otherwise 167 * @throws IllegalArgumentException if the given data path is null or empty 168 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 169 */ 170 public boolean hasExternalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException; 171 172 /** 173 * Checks if there is are comments on the data with the given name 174 * @param dataName name of the data 175 * @return <code>true</code> if there are comments on the data, <code>false</code> otherwise 176 * @throws IllegalArgumentException if the given data name is null or empty 177 * @throws UndefinedItemPathException if the given data name is not defined by the model 178 */ 179 public boolean hasComments(String dataName) throws IllegalArgumentException, UndefinedItemPathException; 180 181 /** 182 * {@inheritDoc} 183 * @return the names of the data contained by this data holder and that are defined by the model 184 */ 185 @Override 186 public Collection<String> getDataNames(); 187 188 /** 189 * Retrieves the value of the data at the given path 190 * @param <T> type of the value to retrieve 191 * @param dataPath path of the data 192 * @return the value of the data or <code>null</code> if not exists or is empty. The object returned may be of a generic class defined by the storage (if the model is unknown). For example, an url may be returned as a String. 193 * @throws IllegalArgumentException if the given data path is null or empty 194 * @throws UndefinedItemPathException if the given data path is not defined by the model 195 * @throws BadItemTypeException if the type defined by the model doesn't match the type of the stored value 196 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 197 */ 198 public default <T extends Object> T getValue(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException 199 { 200 return getValue(dataPath, false); 201 } 202 203 /** 204 * Retrieves the value of the data at the given path 205 * @param <T> type of the value to retrieve 206 * @param dataPath path of the data 207 * @param allowMultiValuedPathSegments <code>true</code> to allow multi-valued segments in the path (not necessarily at the last segment), <code>false</code> otherwise. 208 * If <code>true</code>, if there is no indicated entry for a repeater, the values of all the entries are retrieved 209 * If <code>true</code> and if there are multiple values, all data are retrieved in one array 210 * @return the value of the data or <code>null</code> if allowMultiValuedPathSegments is <code>false</code> and there is no non empty value. The object returned may be of a generic class defined by the storage (if the model is unknown). For example, an url may be returned as a String. 211 * @throws IllegalArgumentException if the given data path is null or empty 212 * @throws UndefinedItemPathException if the given data path is not defined by the model 213 * @throws BadItemTypeException if the type defined by the model doesn't match the type of the stored value 214 * @throws BadDataPathCardinalityException if the managesMultiples boolean is <code>false</code> and the definition of a part of the data path is multiple. Only the last part can be multiple 215 */ 216 public <T extends Object> T getValue(String dataPath, boolean allowMultiValuedPathSegments) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 217 218 /** 219 * Retrieves the value of the data at the given path, or the default value 220 * The returned value is one of those ones, in the order: 221 * <ol> 222 * <li>The value of the data if exists and is not empty</li> 223 * <li>The default value from the model if useDefaultFromModel is <code>true</code> and there is a default value defined by the model</li> 224 * <li>The given default value</li> 225 * </ol> 226 * @param <T> type of the value to retrieve 227 * @param dataPath path of the data 228 * @param useDefaultFromModel true to use the default value from the model, false to use the given default value 229 * @param defaultValue default value used if value is null and useDefaultFromModel is false, or if there is no default value on model 230 * @return the value of the data at the given path 231 * @throws IllegalArgumentException if the given data path is null or empty 232 * @throws UndefinedItemPathException if the given data path is not defined by the model 233 * @throws BadItemTypeException if the type defined by the model doesn't match the type of the stored value 234 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 235 */ 236 public <T extends Object> T getValue(String dataPath, boolean useDefaultFromModel, T defaultValue) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 237 238 /** 239 * Retrieves the local value of the data at the given path 240 * @param <T> type of the value to retrieve 241 * @param dataPath path of the externalizable data 242 * @return the local value of the data or <code>null</code> if not exists or is empty. The object returned may be of a generic class defined by the storage (if the model is unknown). For example, an url may be returned as a String. 243 * @throws IllegalArgumentException if the given data path is null or empty 244 * @throws UndefinedItemPathException if the given data path is not defined by the model 245 * @throws BadItemTypeException if the type defined by the model doesn't match the type of the stored value 246 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 247 */ 248 public <T extends Object> T getLocalValue(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 249 250 /** 251 * Retrieves the external value of the data at the given path 252 * @param <T> type of the value to retrieve 253 * @param dataPath path of the externalizable data 254 * @return the external value of the data or <code>null</code> if not exists or is empty. The object returned may be of a generic class defined by the storage (if the model is unknown). For example, an url may be returned as a String. 255 * @throws IllegalArgumentException if the given data path is null or empty 256 * @throws UndefinedItemPathException if the given data path is not defined by the model 257 * @throws BadItemTypeException if the type defined by the model doesn't match the type of the stored value 258 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 259 */ 260 public <T extends Object> T getExternalValue(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadItemTypeException, BadDataPathCardinalityException; 261 262 /** 263 * Retrieves the status of the externalizable data at the given path 264 * Warning: This method won't check that your data is externalizable. But there is no sense to call it with a non externalizable data 265 * @param dataPath path of the externalizable data 266 * @return the status of the externalizable data at the given path 267 * @throws IllegalArgumentException if the given data path is null or empty 268 * @throws UndefinedItemPathException if the given data path is not defined by the model 269 * @throws BadDataPathCardinalityException if the definition of a part of the data path is multiple. Only the last part can be multiple 270 */ 271 public ExternalizableDataStatus getStatus(String dataPath) throws IllegalArgumentException, UndefinedItemPathException, BadDataPathCardinalityException; 272 273 /** 274 * Retrieve the comments of the data with the given name 275 * @param dataName name of the data 276 * @return the comments of the data 277 * @throws IllegalArgumentException if the given data name is null or empty 278 * @throws UndefinedItemPathException if the given data name is not defined by the model 279 */ 280 public List<DataComment> getComments(String dataName) throws IllegalArgumentException, UndefinedItemPathException; 281 282 /** 283 * Checks if the definition of the element at the given path is multiple 284 * @param path path of the element. No matter if it is a definition or data path (with repeater entry positions) 285 * @return <code>true</code> if the element is multiple, <code>false</code> otherwise 286 * @throws IllegalArgumentException if the given path is null or empty 287 * @throws UndefinedItemPathException if the given path is not defined by the model 288 */ 289 public default boolean isMultiple(String path) throws IllegalArgumentException, UndefinedItemPathException 290 { 291 ModelItem item = getDefinition(path); 292 if (item instanceof ElementDefinition) 293 { 294 return ((ElementDefinition) item).isMultiple(); 295 } 296 else if (item instanceof RepeaterDefinition) 297 { 298 // If the given path represents a repeater , but with no specified entry, consider the data as multiple 299 return !DataHolderHelper.isRepeaterEntryPath(path); 300 } 301 else 302 { 303 // Composites are not multiples 304 return false; 305 } 306 } 307 308 /** 309 * Retrieves the type of the data at the given path 310 * @param <X> type of the item type 311 * @param path path of the data. No matter if it is a definition or data path (with repeater entry positions) 312 * @return the type of the data 313 * @throws IllegalArgumentException if the given data path is null or empty 314 * @throws UndefinedItemPathException if the given data path is not defined by the model 315 */ 316 @SuppressWarnings("unchecked") 317 public default <X extends ModelItemType> X getType(String path) throws IllegalArgumentException, UndefinedItemPathException 318 { 319 return (X) getDefinition(path).getType(); 320 } 321 322 /** 323 * Retrieves the data holder's model 324 * @return the data holder's model 325 */ 326 public Collection<? extends ModelItemContainer> getModel(); 327 328 /** 329 * Retrieves the definition of the data at the given path 330 * @param path path of the data. No matter if it is a definition or data path (with repeater entry positions) 331 * @return the definition of the data 332 * @throws IllegalArgumentException if the given path is null or empty 333 * @throws UndefinedItemPathException if the given path is not defined by the model 334 */ 335 public default ModelItem getDefinition(String path) throws IllegalArgumentException, UndefinedItemPathException 336 { 337 return ModelHelper.getModelItem(path, getModel()); 338 } 339 340 /** 341 * Checks if there is a definition at the given path 342 * @param path path of the data. No matter if it is a definition or data path (with repeater entry positions) 343 * @return <code>true</code> if there is definition at the given path, <code>false</code> otherwise 344 * @throws IllegalArgumentException if the given path is null or empty 345 */ 346 public default boolean hasDefinition(String path) throws IllegalArgumentException 347 { 348 try 349 { 350 getDefinition(path); 351 return true; 352 } 353 catch (UndefinedItemPathException e) 354 { 355 return false; 356 } 357 } 358 359 /** 360 * Generates SAX events for the data in the model of the current {@link DataHolder} 361 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 362 * @throws SAXException if an error occurs during the SAX events generation 363 * @throws BadItemTypeException if the saxed value's type does not matches the stored data 364 */ 365 public default void dataToSAX(ContentHandler contentHandler) throws SAXException, BadItemTypeException 366 { 367 dataToSAX(contentHandler, DataContext.newInstance()); 368 } 369 370 /** 371 * Generates SAX events for the data in the model of the current {@link DataHolder} 372 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 373 * @param context The context of the data to SAX 374 * @throws SAXException if an error occurs during the SAX events generation 375 * @throws BadItemTypeException if the saxed value's type does not matches the stored data 376 */ 377 public default void dataToSAX(ContentHandler contentHandler, DataContext context) throws SAXException, BadItemTypeException 378 { 379 ViewItemAccessor viewItemAccessor = ViewHelper.createViewItemAccessor(getModel()); 380 dataToSAX(contentHandler, viewItemAccessor, context); 381 } 382 383 /** 384 * Generates SAX events for the data in the given view in the current {@link DataHolder} 385 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 386 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items for which generate SAX events 387 * @throws SAXException if an error occurs during the SAX events generation 388 * @throws BadItemTypeException if the saxed value's type does not matches the stored data 389 */ 390 public default void dataToSAX(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor) throws SAXException, BadItemTypeException 391 { 392 dataToSAX(contentHandler, viewItemAccessor, DataContext.newInstance()); 393 } 394 395 /** 396 * Generates SAX events for the data in the given view in the current {@link DataHolder} 397 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 398 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items for which generate SAX events 399 * @param context The context of the data to SAX 400 * @throws SAXException if an error occurs during the SAX events generation 401 * @throws BadItemTypeException if the saxed value's type does not matches the stored data 402 */ 403 public void dataToSAX(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException; 404 405 /** 406 * Generates SAX events for the data in the given view in edition mode in the current {@link DataHolder} 407 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 408 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items for which generate SAX events 409 * @param context The context of the data to SAX 410 * @throws SAXException if an error occurs during the SAX events generation 411 * @throws BadItemTypeException if the saxed value's type does not matches the stored data 412 */ 413 public void dataToSAXForEdition(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException; 414 415 /** 416 * Convert the data in the model of the current {@link DataHolder} 417 * @return The data of the current {@link DataHolder} as JSON 418 * @throws BadItemTypeException if the value's type does not matches the stored data 419 */ 420 public default Map<String, Object> dataToJSON() throws BadItemTypeException 421 { 422 return dataToJSON(DataContext.newInstance()); 423 } 424 425 /** 426 * Convert the data in the model of the current {@link DataHolder} 427 * @param context The context of the data to convert 428 * @return The data of the current {@link DataHolder} as JSON 429 * @throws BadItemTypeException if the value's type does not matches the stored data 430 */ 431 public default Map<String, Object> dataToJSON(DataContext context) throws BadItemTypeException 432 { 433 ViewItemAccessor viewItemAccessor = ViewHelper.createViewItemAccessor(getModel()); 434 return dataToJSON(viewItemAccessor, context); 435 } 436 437 /** 438 * Convert the data in the given view of the current {@link DataHolder} 439 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items to convert 440 * @return The data of the given view as JSON 441 * @throws BadItemTypeException if the value's type does not matches the stored data 442 */ 443 public default Map<String, Object> dataToJSON(ViewItemAccessor viewItemAccessor) throws BadItemTypeException 444 { 445 return dataToJSON(viewItemAccessor, DataContext.newInstance()); 446 } 447 448 /** 449 * Convert the data in the given view of the current {@link DataHolder} 450 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items to convert 451 * @param context The context of the data to convert 452 * @return The data of the given view as JSON 453 * @throws BadItemTypeException if the value's type does not matches the stored data 454 */ 455 public Map<String, Object> dataToJSON(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException; 456 457 /** 458 * Convert the data in the given view in edition mode in the current {@link DataHolder} 459 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items to convert 460 * @param context The context of the data to convert 461 * @return The data of the given view as JSON 462 * @throws BadItemTypeException if the value's type does not matches the stored data 463 */ 464 public Map<String, Object> dataToJSONForEdition(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException; 465 466 /** 467 * Generates SAX events for the comments of the data in the given view in the current {@link DataHolder} 468 * @param contentHandler the {@link ContentHandler} that will receive the SAX events 469 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items for which generate SAX events 470 * @throws SAXException if an error occurs during the SAX events generation 471 */ 472 public default void commentsToSAX(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor) throws SAXException 473 { 474 DataHolderHelper.commentsToSAX(this, contentHandler, viewItemAccessor, StringUtils.EMPTY); 475 } 476 477 /** 478 * Retrieves all data of this DataHolder as a typed-values Map. 479 * @return a Map containing all data. 480 */ 481 public default Map<String, Object> dataToMap() 482 { 483 return dataToMap(DataContext.newInstance()); 484 } 485 486 /** 487 * Retrieves all data of this DataHolder as a typed-values Map. 488 * @param context The context of the data 489 * @return a Map containing all data. 490 */ 491 public default Map<String, Object> dataToMap(DataContext context) 492 { 493 ViewItemAccessor viewItemAccessor = ViewHelper.createViewItemAccessor(getModel()); 494 return dataToMap(viewItemAccessor, context); 495 } 496 497 /** 498 * Retrieves data of this DataHolder as a typed-values Map. 499 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items to include in the resulting Map 500 * @return a Map containing all data. 501 */ 502 public default Map<String, Object> dataToMap(ViewItemAccessor viewItemAccessor) 503 { 504 return dataToMap(viewItemAccessor, DataContext.newInstance()); 505 } 506 507 /** 508 * Retrieves data of this DataHolder as a typed-values Map. 509 * @param viewItemAccessor the {@link ViewItemAccessor} referencing the items to include in the resulting Map 510 * @param context The context of the data 511 * @return a Map containing all data. 512 */ 513 public Map<String, Object> dataToMap(ViewItemAccessor viewItemAccessor, DataContext context); 514 515 /** 516 * Check if there are differences between the given values and the current ones 517 * @param viewItemAccessor The {@link ViewItemAccessor} for all items to check 518 * @param values the values to check 519 * @return <code>true</code> if there are differences, <code>false</code> otherwise 520 * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model 521 * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value 522 */ 523 public boolean hasDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values) throws UndefinedItemPathException, BadItemTypeException; 524 525 /** 526 * Check if there are differences between the given values and the current ones 527 * @param viewItemAccessor The {@link ViewItemAccessor} for all items to check 528 * @param values the values to check 529 * @param context the context of the synchronization 530 * @return <code>true</code> if there are differences, <code>false</code> otherwise 531 * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model 532 * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value 533 */ 534 public boolean hasDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values, SynchronizationContext context) throws UndefinedItemPathException, BadItemTypeException; 535 536 /** 537 * Get the collection of model items where there are differences between the given values and the current ones 538 * @param viewItemAccessor The {@link ViewItemAccessor} for all items to check 539 * @param values the values to check 540 * @return a collection of model items with differences 541 * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model 542 * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value 543 */ 544 public Collection<ModelItem> getDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values) throws UndefinedItemPathException, BadItemTypeException; 545 546 /** 547 * Get the collection of model items where there are differences between the given values and the current ones 548 * @param viewItemAccessor The {@link ViewItemAccessor} for all items to check 549 * @param values the values to check 550 * @param context the context of the synchronization 551 * @return a collection of model items with differences 552 * @throws UndefinedItemPathException if a key in the given Map refers to a data that is not defined by the model 553 * @throws BadItemTypeException if the type defined by the model of one of the Map's key doesn't match the corresponding value 554 */ 555 public Collection<ModelItem> getDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values, SynchronizationContext context) throws UndefinedItemPathException, BadItemTypeException; 556 557 @Override 558 public Optional<? extends ModelAwareDataHolder> getParentDataHolder(); 559 560 @Override 561 public ModelAwareDataHolder getRootDataHolder(); 562}