KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > components > dao > AbstractComponentDao


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2006
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.components.dao;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.riotfamily.cachius.Cache;
37 import org.riotfamily.common.web.event.ContentChangedEvent;
38 import org.riotfamily.components.Component;
39 import org.riotfamily.components.ComponentList;
40 import org.riotfamily.components.ComponentRepository;
41 import org.riotfamily.components.ComponentVersion;
42 import org.riotfamily.components.Location;
43 import org.riotfamily.components.PropertyProcessor;
44 import org.riotfamily.components.VersionContainer;
45 import org.riotfamily.riot.security.AccessController;
46 import org.springframework.beans.factory.InitializingBean;
47 import org.springframework.context.event.ApplicationEventMulticaster;
48 import org.springframework.util.Assert;
49
50 /**
51  * Abstract base class for {@link Component} implementations that delegates
52  * the various CRUD methods to generic load, save, update and delete methods.
53  *
54  * @author Felix Gnass [fgnass at neteye dot de]
55  */

56 public abstract class AbstractComponentDao implements ComponentDao,
57         InitializingBean {
58
59     private static final Log log = LogFactory.getLog(AbstractComponentDao.class);
60
61     private ComponentRepository repository;
62
63     private Cache cache;
64
65     private ApplicationEventMulticaster eventMulticaster;
66
67     public AbstractComponentDao() {
68     }
69
70     public void setRepository(ComponentRepository repository) {
71         this.repository = repository;
72     }
73
74     public void setCache(Cache cache) {
75         this.cache = cache;
76     }
77
78     public void setEventMulticaster(ApplicationEventMulticaster eventMulticaster) {
79         this.eventMulticaster = eventMulticaster;
80     }
81
82     public void afterPropertiesSet() throws Exception JavaDoc {
83         Assert.notNull(repository, "A ComponentRepository must be set.");
84         initDao();
85     }
86
87     protected void initDao() {
88     }
89
90     /**
91      * Loads the ComponentList specified by the given id.
92      */

93     public ComponentList loadComponentList(Long JavaDoc id) {
94         return (ComponentList) loadObject(ComponentList.class, id);
95     }
96
97     /**
98      * Loads the VersionContainer specified by the given id.
99      */

100     public VersionContainer loadVersionContainer(Long JavaDoc id) {
101         return (VersionContainer) loadObject(VersionContainer.class, id);
102     }
103
104     /**
105      * Loads the ComponentVersion specified by the given id.
106      * @since 6.4
107      */

108     public ComponentVersion loadComponentVersion(Long JavaDoc id) {
109         return (ComponentVersion) loadObject(ComponentVersion.class, id);
110     }
111
112     /**
113      * Saves the given ComponentList.
114      */

115     public void saveComponentList(ComponentList list) {
116         list.setLastModified(new Date JavaDoc());
117         list.setLastModifiedBy(AccessController.getCurrentUser().getUserId());
118         saveObject(list);
119     }
120
121     /**
122      * Updates the given ComponentList.
123      */

124     public void updateComponentList(ComponentList list) {
125         if (list.getId() != null) {
126             list.setLastModified(new Date JavaDoc());
127             list.setLastModifiedBy(AccessController.getCurrentUser().getUserId());
128             updateObject(list);
129         }
130     }
131
132     /**
133      * Updates the given VersionContainer.
134      */

135     public void updateVersionContainer(VersionContainer container) {
136         if (container.getId() != null) {
137             updateObject(container);
138         }
139     }
140
141     /**
142      * Updates the given ComponentVersion.
143      */

144     public void updateComponentVersion(ComponentVersion version) {
145         if (version.getId() != null) {
146             updateObject(version);
147         }
148     }
149
150     /**
151      * Returns a list of {@link VersionContainer containers} that can be
152      * modified without affecting the live list. If the preview list does not
153      * already exist a new list is created and populated with the containers
154      * from the live list. This method does not create any copies since the
155      * containers themselves are responsible for managing the different versions.
156      */

157     public List JavaDoc getOrCreatePreviewContainers(ComponentList list) {
158         List JavaDoc previewContainers = list.getPreviewContainers();
159         if (!list.isDirty()) {
160             if (previewContainers == null) {
161                 previewContainers = new ArrayList JavaDoc();
162             }
163             else {
164                 previewContainers.clear();
165             }
166             List JavaDoc liveContainers = list.getLiveContainers();
167             if (liveContainers != null) {
168                 previewContainers.addAll(liveContainers);
169             }
170             list.setPreviewContainers(previewContainers);
171             list.setDirty(true);
172         }
173         return previewContainers;
174     }
175
176     /**
177      * Returns the preview version from the given container. If there is only
178      * a live version, a new preview is created automatically.
179      *
180      * @param container The container to use
181      * @param type The type to use when creating an initial preview version.
182      */

183     public ComponentVersion getOrCreateVersion(
184             VersionContainer container, String JavaDoc type, boolean live) {
185
186         if (live) {
187             ComponentVersion liveVersion = container.getLiveVersion();
188             if (liveVersion == null) {
189                 liveVersion = new ComponentVersion(type);
190                 container.setLiveVersion(liveVersion);
191                 saveObject(liveVersion);
192                 updateVersionContainer(container);
193             }
194             return liveVersion;
195         }
196         else {
197             ComponentList list = container.getList();
198             if (list != null && !list.isDirty()) {
199                 getOrCreatePreviewContainers(list);
200                 updateComponentList(list);
201             }
202             ComponentVersion previewVersion = container.getPreviewVersion();
203             if (previewVersion == null) {
204                 ComponentVersion liveVersion = container.getLiveVersion();
205                 if (liveVersion != null) {
206                     previewVersion = copyComponentVersion(liveVersion);
207                 }
208                 else {
209                     previewVersion = new ComponentVersion(type);
210                     saveObject(previewVersion);
211                 }
212                 container.setPreviewVersion(previewVersion);
213                 updateVersionContainer(container);
214             }
215             return previewVersion;
216         }
217     }
218
219     /**
220      * Inserts a container into a list.
221      */

222     public VersionContainer insertContainer(ComponentList componentList,
223             String JavaDoc type, Map JavaDoc properties, int position, boolean live) {
224
225         List JavaDoc containers = live
226                 ? componentList.getLiveContainers()
227                 : getOrCreatePreviewContainers(componentList);
228
229         VersionContainer container = createVersionContainer(type, properties, live);
230         container.setList(componentList);
231
232         if (position >= 0) {
233             containers.add(position, container);
234         }
235         else {
236             containers.add(container);
237         }
238
239         if (!live) {
240             componentList.setDirty(true);
241         }
242
243         updateComponentList(componentList);
244         return container;
245     }
246
247     /**
248      * Creates a new container, containing a version of the given type.
249      *
250      * @param type The type of the version to create
251      * @param properties Properties of the version to create
252      * @param live Whether to create a preview or live version
253      * @return The newly created container
254      */

255     private VersionContainer createVersionContainer(
256             String JavaDoc type, Map JavaDoc properties, boolean live) {
257
258         VersionContainer container = new VersionContainer();
259         ComponentVersion version = new ComponentVersion(type);
260         version.setProperties(properties);
261         saveObject(version);
262         if (live) {
263             container.setLiveVersion(version);
264         }
265         else {
266             container.setPreviewVersion(version);
267         }
268         saveObject(container);
269         return container;
270     }
271
272     /**
273      * Delete all ComponentLists for the given path
274      * @since 6.4
275      */

276     public void deleteComponentLists(String JavaDoc type, String JavaDoc path) {
277         List JavaDoc componentLists = findComponentLists(type, path);
278         Iterator JavaDoc it = componentLists.iterator();
279         while (it.hasNext()) {
280             ComponentList list = (ComponentList) it.next();
281             deleteComponentList(list);
282         }
283     }
284
285     /**
286      * Deletes the given ComponentList.
287      */

288     public void deleteComponentList(ComponentList list) {
289         List JavaDoc previewList = list.getPreviewContainers();
290         List JavaDoc liveList = list.getLiveContainers();
291         if (liveList != null) {
292             Iterator JavaDoc it = liveList.listIterator();
293             while (it.hasNext()) {
294                 VersionContainer component = (VersionContainer) it.next();
295                 if (previewList == null || !previewList.contains(component)) {
296                     deleteVersionContainer(component);
297                 }
298                 it.remove();
299             }
300         }
301         if (previewList != null) {
302             Iterator JavaDoc it = previewList.listIterator();
303             while (it.hasNext()) {
304                 deleteVersionContainer((VersionContainer) it.next());
305                 it.remove();
306             }
307         }
308         deleteObject(list);
309     }
310
311     /**
312      * Deletes the given VersionContainer.
313      */

314     public void deleteVersionContainer(VersionContainer container) {
315         Iterator JavaDoc it = container.getChildLists().iterator();
316         while (it.hasNext()) {
317             deleteComponentList((ComponentList) it.next());
318         }
319         deleteComponentVersion(container.getLiveVersion());
320         deleteComponentVersion(container.getPreviewVersion());
321         deleteObject(container);
322     }
323
324     /**
325      * Deletes the given ComponentVersion.
326      */

327     public void deleteComponentVersion(ComponentVersion version) {
328         if (version != null) {
329             Component component = repository.getComponent(version);
330             Iterator JavaDoc it = component.getPropertyProcessors().iterator();
331             while (it.hasNext()) {
332                 PropertyProcessor pp = (PropertyProcessor) it.next();
333                 pp.delete(version.getProperties());
334             }
335             deleteObject(version);
336         }
337     }
338
339     /**
340      * Publishes the given VersionContainer.
341      * @return <code>true</code> if there was anything to publish.
342      */

343     public boolean publishContainer(VersionContainer container) {
344         boolean published = false;
345         Set JavaDoc childLists = container.getChildLists();
346         if (childLists != null) {
347             Iterator JavaDoc it = childLists.iterator();
348             while (it.hasNext()) {
349                 ComponentList childList = (ComponentList) it.next();
350                 published |= publishList(childList);
351             }
352         }
353         ComponentVersion preview = container.getPreviewVersion();
354         if (preview != null) {
355             ComponentVersion liveVersion = container.getLiveVersion();
356             if (liveVersion != null) {
357                 deleteComponentVersion(liveVersion);
358             }
359             container.setLiveVersion(preview);
360             container.setPreviewVersion(null);
361             updateVersionContainer(container);
362             published = true;
363             if (container.getList() == null) {
364                 cache.invalidateTaggedItems(VersionContainer.class.getName()
365                         + '#' + container.getId());
366             }
367         }
368         return published;
369     }
370
371     /**
372      * Publishes the given list.
373      * @return <code>true</code> if there was anything to publish
374      */

375     public boolean publishList(ComponentList componentList) {
376         boolean published = false;
377         if (componentList.isDirty()) {
378             log.debug("List " + componentList + " is dirty and will be published.");
379             published = true;
380             List JavaDoc previewList = componentList.getPreviewContainers();
381             List JavaDoc liveList = componentList.getLiveContainers();
382             if (liveList == null) {
383                 liveList = new ArrayList JavaDoc();
384             }
385             else {
386                 Iterator JavaDoc it = liveList.iterator();
387                 while (it.hasNext()) {
388                     VersionContainer container = (VersionContainer) it.next();
389                     if (!previewList.contains(container)) {
390                         deleteVersionContainer(container);
391                         it.remove();
392                     }
393                 }
394                 liveList.clear();
395             }
396             liveList.addAll(previewList);
397             previewList.clear();
398             componentList.setDirty(false);
399             updateComponentList(componentList);
400         }
401
402         Iterator JavaDoc it = componentList.getLiveContainers().iterator();
403         while (it.hasNext()) {
404             VersionContainer container = (VersionContainer) it.next();
405             published |= publishContainer(container);
406         }
407
408         if (eventMulticaster != null) {
409             String JavaDoc path = repository.getUrl(componentList);
410             eventMulticaster.multicastEvent(new ContentChangedEvent(this, path));
411         }
412
413         if (published && cache != null) {
414             String JavaDoc tag = componentList.getLocation().toString();
415             log.debug("Invalidating items tagged as " + tag);
416             cache.invalidateTaggedItems(tag);
417         }
418
419         return published;
420     }
421
422     /**
423      * Discards all changes made to the given list.
424      */

425     public boolean discardList(ComponentList componentList) {
426         boolean discarded = false;
427         List JavaDoc previewList = componentList.getPreviewContainers();
428         List JavaDoc liveList = componentList.getLiveContainers();
429         if (componentList.isDirty()) {
430             discarded = true;
431             componentList.setPreviewContainers(null);
432             componentList.setDirty(false);
433             Iterator JavaDoc it = previewList.iterator();
434             while (it.hasNext()) {
435                 VersionContainer container = (VersionContainer) it.next();
436                 if (liveList == null || !liveList.contains(container)) {
437                     deleteVersionContainer(container);
438                     it.remove();
439                 }
440             }
441             updateComponentList(componentList);
442         }
443         Iterator JavaDoc it = liveList.iterator();
444         while (it.hasNext()) {
445             VersionContainer container = (VersionContainer) it.next();
446             discarded |= discardContainer(container);
447         }
448         return discarded;
449     }
450
451     /**
452      * Discards all changes made to the given VersionContainer.
453      * @return <code>true</code> if there was anything to discard.
454      */

455     public boolean discardContainer(VersionContainer container) {
456         boolean discarded = false;
457         Set JavaDoc childLists = container.getChildLists();
458         if (childLists != null) {
459             Iterator JavaDoc it = childLists.iterator();
460             while (it.hasNext()) {
461                 ComponentList childList = (ComponentList) it.next();
462                 discarded |= discardList(childList);
463             }
464         }
465         ComponentVersion preview = container.getPreviewVersion();
466         if (preview != null) {
467             container.setPreviewVersion(null);
468             updateVersionContainer(container);
469             deleteComponentVersion(preview);
470             discarded = true;
471         }
472         return discarded;
473     }
474
475     /**
476      * Creates copies of all ComponentLists under the given path and sets
477      * their path to the specified <code>newPath</code>.
478      */

479     public void copyComponentLists(String JavaDoc type, String JavaDoc oldPath, String JavaDoc newPath) {
480         List JavaDoc lists = findComponentLists(type, oldPath);
481         if (lists != null) {
482             Iterator JavaDoc it = lists.iterator();
483             while (it.hasNext()) {
484                 ComponentList list = (ComponentList) it.next();
485                 ComponentList copy = copyComponentList(list, newPath);
486                 saveComponentList(copy);
487             }
488         }
489     }
490
491     private ComponentList copyComponentList(ComponentList list, String JavaDoc path) {
492         ComponentList copy = new ComponentList();
493         Location location = new Location(list.getLocation());
494         location.setPath(path);
495         copy.setLocation(location);
496         copy.setDirty(list.isDirty());
497         copy.setLiveContainers(copyContainers(list.getLiveContainers(), path));
498         copy.setPreviewContainers(copyContainers(list.getPreviewContainers(), path));
499         return copy;
500     }
501
502     private List JavaDoc copyContainers(List JavaDoc source, String JavaDoc path) {
503         if (source == null) {
504             return null;
505         }
506         List JavaDoc dest = new ArrayList JavaDoc(source.size());
507         Iterator JavaDoc it = source.iterator();
508         while (it.hasNext()) {
509             VersionContainer container = (VersionContainer) it.next();
510             dest.add(copyVersionContainer(container, path));
511         }
512         return dest;
513     }
514
515     private VersionContainer copyVersionContainer(VersionContainer container, String JavaDoc path) {
516         VersionContainer copy = new VersionContainer();
517         if (container.getLiveVersion() != null) {
518             copy.setLiveVersion(copyComponentVersion(
519                     container.getLiveVersion()));
520         }
521         if (container.getPreviewVersion() != null) {
522             copy.setPreviewVersion(copyComponentVersion(
523                     container.getPreviewVersion()));
524         }
525         Set JavaDoc childLists = container.getChildLists();
526         if (childLists != null) {
527             HashSet JavaDoc clonedLists = new HashSet JavaDoc();
528             Iterator JavaDoc it = childLists.iterator();
529             while (it.hasNext()) {
530                 ComponentList list = (ComponentList) it.next();
531                 ComponentList clonedList = copyComponentList(list, path);
532                 clonedList.setParent(copy);
533                 clonedLists.add(clonedList);
534             }
535             copy.setChildLists(clonedLists);
536         }
537         return copy;
538     }
539
540     private ComponentVersion copyComponentVersion(ComponentVersion version) {
541         Component component = repository.getComponent(version);
542         ComponentVersion copy = new ComponentVersion(version);
543         if (component.getPropertyProcessors() != null) {
544             Iterator JavaDoc it = component.getPropertyProcessors().iterator();
545             while (it.hasNext()) {
546                 PropertyProcessor pp = (PropertyProcessor) it.next();
547                 pp.copy(version.getProperties(), copy.getProperties());
548             }
549         }
550         return copy;
551     }
552
553     protected abstract Object JavaDoc loadObject(Class JavaDoc clazz, Long JavaDoc id);
554
555     protected abstract void saveObject(Object JavaDoc object);
556
557     protected abstract void updateObject(Object JavaDoc object);
558
559     protected abstract void deleteObject(Object JavaDoc object);
560
561 }
562
Popular Tags