001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * *** 008 * 009 * Community License: GPL 3.0 010 * 011 * This file is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU General Public License as published 013 * by the Free Software Foundation, either version 3 of the License, 014 * or (at your option) any later version. 015 * 016 * This file is distributed in the hope that it will be useful, but 017 * WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * 024 * *** 025 * 026 * Available Commercial License: GraniteDS SLA 1.0 027 * 028 * This is the appropriate option if you are creating proprietary 029 * applications and you are not prepared to distribute and share the 030 * source code of your application under the GPL v3 license. 031 * 032 * Please visit http://www.granitedataservices.com/license for more 033 * details. 034 */ 035package org.granite.client.tide.data; 036 037import java.util.List; 038import java.util.Map; 039 040import org.granite.client.tide.Context; 041import org.granite.client.tide.data.spi.DataManager; 042import org.granite.client.tide.data.spi.MergeContext; 043import org.granite.client.tide.data.spi.DataManager.TrackingHandler; 044import org.granite.client.tide.server.ServerSession; 045 046/** 047 * EntityManager is the interface for entity management (!) 048 * It is implemented by the Tide context 049 * 050 * @author William DRAI 051 */ 052public interface EntityManager { 053 054 /** 055 * Return the entity manager id 056 * 057 * @return the entity manager id 058 */ 059 public String getId(); 060 061 /** 062 * Return the entity manager state 063 * 064 * @return the entity manager state 065 */ 066 public boolean isActive(); 067 068 /** 069 * Clear entity cache 070 */ 071 public void clearCache(); 072 073 /** 074 * Clear the current context 075 * Destroys all components/context variables 076 */ 077 public void clear(); 078 079 /** 080 * Data manager for this entity manager 081 * @return data manager 082 */ 083 public DataManager getDataManager(); 084 085 /** 086 * Tracking handler for this entity manager 087 * @return tracking handler 088 */ 089 public TrackingHandler getTrackingHandler(); 090 091 /** 092 * Allow uninitialize of persistent collections 093 * @param allowed allow uninitialize of collections 094 */ 095 public void setUninitializeAllowed(boolean allowed); 096 097 /** 098 * Allow uninitialize of persistent collections ? 099 * @return allow uninitialize of collections 100 */ 101 public boolean isUninitializeAllowed(); 102 103 /** 104 * Setter for the remote initializer implementation 105 * 106 * @param remoteInitializer instance of IRemoteInitializer 107 */ 108 public void setRemoteInitializer(RemoteInitializer remoteInitializer); 109 110 /** 111 * Setter for the remote validator implementation 112 * 113 * @param remoteValidator instance of IRemoteValidator 114 */ 115 public void setRemoteValidator(RemoteValidator remoteValidator); 116 117 /** 118 * Create a new temporary entity manager 119 * 120 * @return a temporary entity manager 121 */ 122 public EntityManager newTemporaryEntityManager(); 123 124 125 /** 126 * Register a reference to the provided object with either a parent or res 127 * 128 * @param entity an entity 129 * @param parent the parent entity 130 * @param propName name of the parent entity property that references the entity 131 */ 132 public void addReference(Object entity, Object parent, String propName); 133 134 /** 135 * Remove a reference on the provided object 136 * 137 * @param entity an entity 138 * @param parent the parent entity to dereference 139 * @param propName name of the parent entity property that references the entity 140 */ 141 public boolean removeReference(Object entity, Object parent, String propName); 142 143 /** 144 * Entity manager is dirty when any entity/collection/map has been modified 145 * 146 * @return is dirty 147 */ 148 public boolean isDirty(); 149 150 /** 151 * Entity is dirty when any direct property has been modified 152 * @param entity 153 * 154 * @return is dirty 155 */ 156 public boolean isDirtyEntity(Object entity); 157 158 /** 159 * Entity is deep dirty when any element in its object graph has been modified 160 * @param entity root of the entity graph 161 * 162 * @return is dirty 163 */ 164 public boolean isDeepDirtyEntity(Object entity); 165 166 /** 167 * Indicates if the entity is persisted on the server (id/version not null/NaN) 168 * 169 * @param entity an entity 170 * @return true if saved 171 */ 172 public boolean isPersisted(Object entity); 173 174 /** 175 * Retrieve an entity in the cache from its uid 176 * 177 * @param object an entity 178 * @param nullIfAbsent return null if entity not cached in context 179 */ 180 public Object getCachedObject(Object object, boolean nullIfAbsent); 181 182 /** 183 * Return the owner entity for the specified object (collection/map, embedded object or associated object) 184 * @param object an object 185 * @return array containing the owner entity and the property name or null if not found 186 */ 187 public Object[] getOwnerEntity(Object object); 188 189 /** 190 * Initialize the merge context in the current thread 191 * MergeContext should be released at the end of the process 192 * @return current merge context 193 */ 194 public MergeContext initMerge(); 195 196 /** 197 * Merge an object in the local context 198 * 199 * @param mergeContext current merge context 200 * @param obj object to merge 201 * @param previous previous instance 202 * @param parent parent/owning entity 203 * @param propertyName property name from the owning entity 204 * @param forceUpdate true to force update of the destination object even if versions do not match 205 * @return merged object 206 */ 207 public Object mergeExternal(final MergeContext mergeContext, Object obj, Object previous, Object parent, String propertyName, boolean forceUpdate); 208 209 /** 210 * Merge an object coming from a remote location (in general from a service) in the local context 211 * 212 * @param obj external object 213 * @param prev existing local object to merge with 214 * @param externalDataSessionId sessionId from which the data is coming (other user/server), null if local or current user session 215 * @param removals list of entities to remove from the entity manager cache 216 * @param persists list of entities newly persisted to be added in the entity manager cache 217 * 218 * @return merged object (should === previous when previous not null) 219 */ 220 public Object mergeExternalData(Object obj, Object prev, String externalDataSessionId, List<Object> removals, List<Object> persists); 221 222 /** 223 * Merge an object coming from a remote location (in general from a service) in the local context 224 * 225 * @param serverSession the current server session 226 * @param obj external object 227 * 228 * @return merged object 229 */ 230 public Object mergeExternalData(ServerSession serverSession, Object obj); 231 232 /** 233 * Merge an object coming from a remote location (in general from a service) in the local context 234 * 235 * @param serverSession the current server session 236 * @param obj external object 237 * @param prev existing local object to merge with 238 * @param externalDataSessionId sessionId from which the data is coming (other user/server), null if local or current user session 239 * @param removals array of entities to remove from the entity manager cache 240 * @param persists list of entities newly persisted to be added in the entity manager cache 241 * 242 * @return merged object (should === previous when previous not null) 243 */ 244 public Object mergeExternalData(ServerSession serverSession, Object obj, Object prev, String externalDataSessionId, List<Object> removals, List<Object> persists); 245 246 /** 247 * Merge an object coming from a remote location (in general from a service) in the local context 248 * 249 * @param obj external object 250 * 251 * @return merged object 252 */ 253 public Object mergeExternalData(Object obj); 254 255 // public Object internalMergeExternalData(MergeContext mergeContext, Object obj, Object prev, List<Object> removals); 256 257 /** 258 * Merge an object coming from another entity manager (in general in the global context) in the local context 259 * 260 * @param sourceEntityManager source context of incoming data 261 * @param obj external object 262 * @param externalDataSessionId is merge from external data 263 * @param uninitializing the merge should uninitialize all collections/entities when possible 264 * 265 * @return merged object (should === previous when previous not null) 266 */ 267 public Object mergeFromEntityManager(EntityManager sourceEntityManager, Object obj, String externalDataSessionId, boolean uninitializing); 268 269 /** 270 * Merge conversation entity manager context variables in global entity manager 271 * Only applicable to conversation contexts 272 * 273 * @param entityManager conversation entity manager 274 */ 275 public void mergeInEntityManager(EntityManager entityManager); 276 277 /** 278 * Discard changes of entity from last version received from the server 279 * 280 * @param entity entity to restore 281 */ 282 public void resetEntity(Object entity); 283 284 /** 285 * Discard changes of all cached entities from last version received from the server 286 */ 287 public void resetAllEntities(); 288 289 /** 290 * Current map of saved properties for the specified entity 291 * @param entity an entity 292 * 293 * @return saved properties for this entity 294 */ 295 public Map<String, Object> getSavedProperties(Object entity); 296 297 /** 298 * Kinds of updates than can be received from the server 299 */ 300 public static enum UpdateKind { 301 PERSIST, 302 UPDATE, 303 REMOVE, 304 REFRESH, 305 CONFLICT; 306 307 private static final String DATA_EVENT_PREFIX = "org.granite.client.tide.data."; 308 309 public static UpdateKind forName(String kind) { 310 if ("PERSIST".equals(kind)) 311 return PERSIST; 312 else if ("UPDATE".equals(kind)) 313 return UPDATE; 314 else if ("REMOVE".equals(kind)) 315 return REMOVE; 316 throw new IllegalArgumentException("Unknown update kind " + kind); 317 } 318 319 public String eventName() { 320 return DATA_EVENT_PREFIX + name().toLowerCase(); 321 } 322 323 public <T> String eventName(Class<T> entityClass) { 324 return DATA_EVENT_PREFIX + name().toLowerCase() + "." + entityClass.getSimpleName(); 325 } 326 } 327 328 /** 329 * Update received from the server 330 */ 331 public static class Update { 332 333 private final UpdateKind kind; 334 private Object entity; 335 336 public Update(UpdateKind kind, Object entity) { 337 this.kind = kind; 338 this.entity = entity; 339 } 340 341 public UpdateKind getKind() { 342 return kind; 343 } 344 345 public Object getEntity() { 346 return entity; 347 } 348 349 public void setEntity(Object entity) { 350 this.entity = entity; 351 } 352 353 public static Update forUpdate(String kind, Object entity) { 354 return new Update(UpdateKind.forName(kind), entity); 355 } 356 } 357 358 /** 359 * Handle data updates 360 * 361 * @param mergeContext current merge context 362 * @param sourceSessionId sessionId from which data updates come (null when from current session) 363 * @param updates list of data updates 364 */ 365 public void handleUpdates(MergeContext mergeContext, String sourceSessionId, List<Update> updates); 366 367 /** 368 * Dispatch update events on the context 369 * @param context tide context 370 * @param updates list of data updates 371 */ 372 public void raiseUpdateEvents(Context context, List<EntityManager.Update> updates); 373 374 /** 375 * Register a listener for data conflicts 376 * @param listener listener 377 */ 378 public void addListener(DataConflictListener listener); 379 380 /** 381 * Unregister a listener for data conflicts 382 * @param listener listener 383 */ 384 public void removeListener(DataConflictListener listener); 385 386 /** 387 * Accept values for conflict 388 * 389 * @param conflict conflict 390 * @param acceptClient true: keep client changes, false: override with server changes 391 */ 392 public void acceptConflict(Conflict conflict, boolean acceptClient); 393 394 /** 395 * Trigger remote initialization of lazy-loaded objects 396 * 397 * @param serverSession current server session 398 * @param entity owner entity 399 * @param propertyName property name 400 * @param object a lazily loaded object 401 * 402 * @return true if initialization triggered 403 */ 404 public boolean initializeObject(ServerSession serverSession, Object entity, String propertyName, Object object); 405 406 /** 407 * Trigger remote validation of objects 408 * 409 * @param object an object to remotely validate 410 * @param property a property to validate 411 * @param value value to check 412 * 413 * @return true if validation triggered 414 */ 415 public boolean validateObject(Object object, String property, Object value); 416 417 418 public static interface Propagation { 419 420 public void propagate(Object entity, Function func); 421 } 422 423 public static interface Function { 424 425 public void execute(EntityManager entityManager, Object entity); 426 } 427 428 /** 429 * Set the propagation manager 430 * 431 * @param propagation propagation function that will visit child entity managers 432 */ 433 public void setEntityManagerPropagation(Propagation propagation); 434 435 public static interface PropagationPolicy { 436 437 public void propagate(); 438 } 439}