KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > content > cleanup > ContentStoreCleaner


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.content.cleanup;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.alfresco.error.AlfrescoRuntimeException;
26 import org.alfresco.repo.content.ContentStore;
27 import org.alfresco.repo.node.db.NodeDaoService;
28 import org.alfresco.repo.transaction.TransactionUtil;
29 import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
30 import org.alfresco.service.cmr.dictionary.DictionaryService;
31 import org.alfresco.service.cmr.repository.ContentData;
32 import org.alfresco.service.cmr.repository.ContentReader;
33 import org.alfresco.service.transaction.TransactionService;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37 /**
38  * This component is responsible for finding orphaned content in a given
39  * content store or stores. Deletion handlers can be provided to ensure
40  * that the content is moved to another location prior to being removed
41  * from the store(s) being cleaned.
42  *
43  * @author Derek Hulley
44  */

45 public class ContentStoreCleaner
46 {
47     private static Log logger = LogFactory.getLog(ContentStoreCleaner.class);
48     
49     private DictionaryService dictionaryService;
50     private NodeDaoService nodeDaoService;
51     private TransactionService transactionService;
52     private List JavaDoc<ContentStore> stores;
53     private List JavaDoc<ContentStoreCleanerListener> listeners;
54     private int protectDays;
55     
56     public ContentStoreCleaner()
57     {
58         this.stores = new ArrayList JavaDoc<ContentStore>(0);
59         this.listeners = new ArrayList JavaDoc<ContentStoreCleanerListener>(0);
60         this.protectDays = 7;
61     }
62
63     /**
64      * @param dictionaryService used to determine which properties are content properties
65      */

66     public void setDictionaryService(DictionaryService dictionaryService)
67     {
68         this.dictionaryService = dictionaryService;
69     }
70
71     /**
72      * @param nodeDaoService used to get the property values
73      */

74     public void setNodeDaoService(NodeDaoService nodeDaoService)
75     {
76         this.nodeDaoService = nodeDaoService;
77     }
78
79     /**
80      * @param transactionService the component to ensure proper transactional wrapping
81      */

82     public void setTransactionService(TransactionService transactionService)
83     {
84         this.transactionService = transactionService;
85     }
86
87     /**
88      * @param stores the content stores to clean
89      */

90     public void setStores(List JavaDoc<ContentStore> stores)
91     {
92         this.stores = stores;
93     }
94
95     /**
96      * @param listeners the listeners that can react to deletions
97      */

98     public void setListeners(List JavaDoc<ContentStoreCleanerListener> listeners)
99     {
100         this.listeners = listeners;
101     }
102
103     /**
104      * Set the minimum number of days old that orphaned content must be
105      * before deletion is possible. The default is 7 days.
106      *
107      * @param protectDays minimum age (in days) of deleted content
108      */

109     public void setProtectDays(int protectDays)
110     {
111         this.protectDays = protectDays;
112     }
113     
114     /**
115      * Perform basic checks to ensure that the necessary dependencies were injected.
116      */

117     private void checkProperties()
118     {
119         if (dictionaryService == null)
120         {
121             throw new AlfrescoRuntimeException("Property 'dictionaryService' not set");
122         }
123         if (nodeDaoService == null)
124         {
125             throw new AlfrescoRuntimeException("Property 'nodeDaoService' not set");
126         }
127         if (transactionService == null)
128         {
129             throw new AlfrescoRuntimeException("Property 'transactionService' not set");
130         }
131         if (stores == null || stores.size() == 0)
132         {
133             throw new AlfrescoRuntimeException("Property 'stores' not set");
134         }
135         if (listeners == null)
136         {
137             throw new AlfrescoRuntimeException("Property 'listeners' not set");
138         }
139         
140         // check the protect days
141
if (protectDays < 0)
142         {
143             throw new AlfrescoRuntimeException("Property 'protectDays' must be 0 or greater (0 is not recommended)");
144         }
145         else if (protectDays == 0)
146         {
147             logger.warn(
148                     "Property 'protectDays' is set to 0. " +
149                     "It is possible that in-transaction content will be deleted.");
150         }
151     }
152     
153     private Set JavaDoc<String JavaDoc> getValidUrls()
154     {
155         // wrap to make the request in a transaction
156
TransactionWork<List JavaDoc<String JavaDoc>> getUrlsWork = new TransactionWork<List JavaDoc<String JavaDoc>>()
157         {
158             public List JavaDoc<String JavaDoc> doWork() throws Exception JavaDoc
159             {
160                 return nodeDaoService.getContentDataStrings();
161             };
162         };
163         // execute in READ-ONLY txn
164
List JavaDoc<String JavaDoc> contentDataStrings = TransactionUtil.executeInUserTransaction(
165                 transactionService,
166                 getUrlsWork,
167                 true);
168         
169         // get all valid URLs
170
Set JavaDoc<String JavaDoc> validUrls = new HashSet JavaDoc<String JavaDoc>(contentDataStrings.size());
171         // convert the strings to objects and extract the URL
172
for (String JavaDoc contentDataString : contentDataStrings)
173         {
174             ContentData contentData = ContentData.createContentProperty(contentDataString);
175             if (contentData.getContentUrl() != null)
176             {
177                 // a URL was present
178
validUrls.add(contentData.getContentUrl());
179             }
180         }
181         // done
182
if (logger.isDebugEnabled())
183         {
184             logger.debug("Found " + validUrls.size() + " valid URLs in metadata");
185         }
186         return validUrls;
187     }
188     
189     public void execute()
190     {
191         checkProperties();
192         Set JavaDoc<String JavaDoc> validUrls = getValidUrls();
193         // now clean each store in turn
194
for (ContentStore store : stores)
195         {
196             clean(validUrls, store);
197         }
198     }
199     
200     private void clean(Set JavaDoc<String JavaDoc> validUrls, ContentStore store)
201     {
202         Date JavaDoc checkAllBeforeDate = new Date JavaDoc(System.currentTimeMillis() - (long) protectDays * 3600L * 1000L * 24L);
203         // get the store's URLs
204
Set JavaDoc<String JavaDoc> storeUrls = store.getUrls(null, checkAllBeforeDate);
205         // remove all URLs that occur in the validUrls
206
storeUrls.removeAll(validUrls);
207         // now clean the store
208
for (String JavaDoc url : storeUrls)
209         {
210             ContentReader sourceReader = store.getReader(url);
211             // announce this to the listeners
212
for (ContentStoreCleanerListener listener : listeners)
213             {
214                 // get a fresh reader
215
ContentReader listenerReader = sourceReader.getReader();
216                 // call it
217
listener.beforeDelete(listenerReader);
218             }
219             // delete it
220
store.delete(url);
221             
222             if (logger.isDebugEnabled())
223             {
224                 logger.debug("Removed URL from store: \n" +
225                         " Store: " + store + "\n" +
226                         " URL: " + url);
227             }
228         }
229     }
230 }
231
Popular Tags