2 * Copyright (C) 2014 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.session
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Arrays
;
13 import java
.util
.Collection
;
14 import java
.util
.List
;
16 import java
.util
.UUID
;
18 import org
.apache
.log4j
.Logger
;
20 import eu
.etaxonomy
.cdm
.api
.service
.IService
;
21 import eu
.etaxonomy
.cdm
.api
.service
.UpdateResult
;
22 import eu
.etaxonomy
.cdm
.cache
.CdmTransientEntityCacher
;
23 //import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher;
24 import eu
.etaxonomy
.cdm
.cache
.EntityCacherDebugResult
;
25 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
26 import eu
.etaxonomy
.cdm
.persistence
.dao
.initializer
.IBeanInitializer
;
27 import eu
.etaxonomy
.cdm
.persistence
.dto
.MergeResult
;
28 import eu
.etaxonomy
.taxeditor
.remoting
.cache
.ConversationalTransientEntityCacher
;
29 import net
.sf
.ehcache
.statistics
.FlatStatistics
;
32 * NOTE : It would be nice to have this class performing merge / delete operations
33 * using services, but this is only possible if we can 'intelligently'
34 * get from a model class to the corresponding service class
39 public class CdmEntitySession
implements ICdmEntitySession
{
41 private static final Logger logger
= Logger
.getLogger(CdmEntitySession
.class);
43 private final CdmEntitySessionManager cdmEntitySessionManager
;
45 private final ICdmEntitySessionEnabled sessionOwner
;
47 private ConversationalTransientEntityCacher cdmTransientEntityCacher
;
49 private List
<ICdmEntitySessionEnabled
> changeObservers
;
51 public CdmEntitySession(ICdmEntitySessionEnabled sessionOwner
, CdmEntitySessionManager cdmEntitySessionManager
) {
52 this.sessionOwner
= sessionOwner
;
53 this.cdmEntitySessionManager
= cdmEntitySessionManager
;
54 init(sessionOwner
, cdmEntitySessionManager
);
57 private void init(ICdmEntitySessionEnabled sessionOwner
, CdmEntitySessionManager cdmEntitySessionManager
) {
58 this.cdmTransientEntityCacher
= new ConversationalTransientEntityCacher(sessionOwner
);
59 this.changeObservers
= new ArrayList
<>();
60 cdmEntitySessionManager
.addToOwnerSessionMap(sessionOwner
, this);
64 public <O
extends Object
> O
load(O obj
, boolean update
) {
65 return cdmTransientEntityCacher
.load(obj
, update
);
69 public <T
extends CdmBase
> T
load(T cdmBase
, boolean update
) {
70 return cdmTransientEntityCacher
.load(cdmBase
, update
);
74 public UpdateResult
load(UpdateResult updateResult
, boolean update
) {
75 return cdmTransientEntityCacher
.load(updateResult
, update
);
79 public <T
extends CdmBase
> MergeResult
<T
> load(MergeResult
<T
> mergeResult
, boolean update
) {
80 return cdmTransientEntityCacher
.load(mergeResult
, update
);
84 public <T
extends CdmBase
> void update() {
85 Collection
<T
> rootEntities
= getRootEntities();
86 if(rootEntities
!= null) {
87 for(T rootEntity
: rootEntities
) {
88 load(rootEntity
, true);
94 // public <T extends ICdmBase> void update(T cdmBase, Set<CdmBase> affectedObjects) {
95 // addEvent(cdmBase, affectedObjects, EventType.UPDATE);
99 // public <T extends ICdmBase> void update(T cdmBase, CdmBase affectedObject) {
100 // Set<CdmBase> set = new HashSet<CdmBase>();
101 // set.add(affectedObject);
102 // addEvent(cdmBase, set, EventType.UPDATE);
107 // public <T extends ICdmBase> void delete(T cdmBase, Set<CdmBase> affectedObjects) {
108 // addEvent(cdmBase, affectedObjects, EventType.DELETE);
112 // public <T extends ICdmBase> void delete(Set<T> cdmBases, Set<CdmBase> affectedObjects) {
113 // addEvent(cdmBases, affectedObjects, EventType.DELETE);
118 public <T
extends CdmBase
> EntityCacherDebugResult
debug(T cdmBase
) {
119 return debug(Arrays
.asList(cdmBase
), true);
123 public <T
extends CdmBase
> EntityCacherDebugResult
debug(Collection
<T
> rootEntities
, boolean includeIgnored
) {
124 EntityCacherDebugResult entityCacherDebugResult
=
125 new EntityCacherDebugResult(cdmTransientEntityCacher
, rootEntities
, includeIgnored
);
126 return entityCacherDebugResult
;
130 public <T
extends CdmBase
> EntityCacherDebugResult
debug(boolean includeIgnored
) {
131 return debug(getRootEntities(), includeIgnored
);
135 public <T
extends CdmBase
> Collection
<T
> load(Collection
<T
> cdmBaseList
, boolean update
) {
136 return cdmTransientEntityCacher
.load(cdmBaseList
, update
);
140 public void setEntitiesAsLatest() {
141 //FIXME:Remoting need to think more about whether we really need this
142 // List<CdmBase> entities = cdmTransientEntityCacher.getAllEntities();
143 // for(CdmBase entity : entities) {
144 // cdmEntitySessionManager.setEntityAsLatest(entity);
150 logger
.info("Binding session with owner " + sessionOwner
.toString());
151 if(!cdmEntitySessionManager
.contains(sessionOwner
)) {
152 init(sessionOwner
, cdmEntitySessionManager
);
154 cdmEntitySessionManager
.bind(sessionOwner
);
158 public void dispose() {
160 cdmTransientEntityCacher
.dispose();
161 changeObservers
.clear();
162 cdmEntitySessionManager
.remove(sessionOwner
);
166 // public void addEvent(ICdmBase cdmBase, Set<CdmBase> affectedObjects, EventType eventType) {
167 // affectedObjects = (Set<CdmBase>) load(affectedObjects, true);
168 // CdmDataChangeEvent cdce = CdmDataChangeEvent.NewInstance((CdmBase)cdmBase, affectedObjects, eventType);
169 // CdmPostDataChangeObservableListener.getDefault().notifyObservers(cdce);
173 * Returns a persisted entity specified by the <code>uuid</code>
174 * or null if the entity does not exist,
175 * loads it to the entityCacher
183 public <T
extends CdmBase
> T
remoteLoad(IService
<T
> service
, UUID uuid
) {
184 T cdmBase
= service
.load(uuid
);
185 return load(cdmBase
, false);
189 * Returns the cdm entity specified by the <code>uuid</code>,
190 * recursively initializes all bean properties given in the
191 * <code>propertyPaths</code> parameter,
192 * the loaded entity is also loaded to the entityCache
194 * For detailed description and examples <b>please refer to:</b>
195 * {@link IBeanInitializer#initialize(Object, List)}
199 * @param propertyPath
204 public <T
extends CdmBase
> T
remoteLoad(IService
<T
> service
, UUID uuid
, List
<String
> propertyPaths
) {
205 T cdmBase
= service
.load(uuid
, propertyPaths
);
206 return load(cdmBase
, false);
210 public <T
extends CdmBase
> UUID
remoteSave(IService
<T
> service
, T cdmBase
) {
211 UUID uuid
= service
.save(cdmBase
).getUuid();
217 public <T
extends CdmBase
> T
remoteUpdate(IService
<T
> service
, T cdmBase
) {
218 T mergedCdmBase
= service
.merge(cdmBase
, true).getMergedEntity();
219 return mergedCdmBase
;
223 public boolean isActive() {
224 return cdmEntitySessionManager
.getActiveSession() == this;
228 public ICdmEntitySessionEnabled
getOwner() {
233 public FlatStatistics
getCacheStatistics() {
234 return cdmTransientEntityCacher
.getCacheStatistics();
238 public <T
extends CdmBase
> Collection
<T
> getRootEntities() {
239 return sessionOwner
.getRootEntities();
242 public CdmTransientEntityCacher
getCacher() {
243 return cdmTransientEntityCacher
;
247 public List
<String
> getPropertyPaths(Object obj
) {
248 Map
<Object
, List
<String
>> propertyPathsMap
= sessionOwner
.getPropertyPathsMap();
249 if(propertyPathsMap
== null || propertyPathsMap
.isEmpty()) {
252 return propertyPathsMap
.get(obj
);
255 //this method is called by DefaultNewEntityListener whenever
256 //a new entity is created (constructor call) while the current
259 public void addNewCdmEntity(CdmBase newEntity
) {
260 cdmTransientEntityCacher
.load(newEntity
);