KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > staticexport > A_CmsStaticExportHandler


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/staticexport/A_CmsStaticExportHandler.java,v $
3  * Date : $Date: 2006/09/20 09:28:45 $
4  * Version: $Revision: 1.8 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.staticexport;
33
34 import org.opencms.db.CmsPublishedResource;
35 import org.opencms.file.CmsObject;
36 import org.opencms.file.CmsResource;
37 import org.opencms.file.CmsResourceFilter;
38 import org.opencms.file.CmsVfsResourceNotFoundException;
39 import org.opencms.main.CmsException;
40 import org.opencms.main.CmsLog;
41 import org.opencms.main.OpenCms;
42 import org.opencms.report.I_CmsReport;
43 import org.opencms.security.CmsSecurityException;
44 import org.opencms.util.CmsFileUtil;
45 import org.opencms.util.CmsStringUtil;
46 import org.opencms.util.CmsUUID;
47
48 import java.io.File JavaDoc;
49 import java.io.FileFilter JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.HashSet JavaDoc;
52 import java.util.Iterator JavaDoc;
53 import java.util.List JavaDoc;
54 import java.util.Set JavaDoc;
55
56 import org.apache.commons.logging.Log;
57
58 /**
59  * Abstract base implementation for the <code>{@link I_CmsStaticExportHandler}</code> interface.<p>
60  *
61  * This class provides several util methods to be used by static export handlers.
62  *
63  * @author Michael Emmerich
64  *
65  * @version $Revision: 1.8 $
66  *
67  * @since 6.1.7
68  *
69  * @see I_CmsStaticExportHandler
70  *
71  */

72 public abstract class A_CmsStaticExportHandler implements I_CmsStaticExportHandler {
73
74     /**
75      * Implements the file filter used to remove variants with parameters of a base file.<p>
76      */

77     private class PrefixFileFilter implements FileFilter JavaDoc {
78
79         /** The extension. */
80         private String JavaDoc m_baseExtension;
81
82         /** The base file. */
83         private String JavaDoc m_baseName;
84
85         /**
86          * Creates a new instance of PrefixFileFilter.<p>
87          *
88          * @param baseFile the base file to compare with.
89          */

90         public PrefixFileFilter(File JavaDoc baseFile) {
91
92             String JavaDoc fileName = baseFile.getName();
93             m_baseExtension = CmsFileUtil.getFileExtension(fileName);
94             m_baseName = fileName + "_";
95         }
96
97         /**
98          * Accepts the given file if its name starts with the name of of the base file (wo extension)
99          * and ends with the extension.<p>
100          *
101          * @see java.io.FileFilter#accept(java.io.File)
102          */

103         public boolean accept(File JavaDoc f) {
104
105             return f.getName().startsWith(m_baseName) && f.getName().endsWith(m_baseExtension);
106         }
107     }
108
109     /** The log object for this class. */
110     private static final Log LOG = CmsLog.getLog(A_CmsStaticExportHandler.class);
111
112     /** Indicates if this content handler is busy. */
113     protected boolean m_busy;
114
115     /**
116      * @see org.opencms.staticexport.I_CmsStaticExportHandler#isBusy()
117      */

118     public boolean isBusy() {
119
120         return m_busy;
121     }
122
123     /**
124      * @see org.opencms.staticexport.I_CmsStaticExportHandler#performEventPublishProject(org.opencms.util.CmsUUID, org.opencms.report.I_CmsReport)
125      */

126     public abstract void performEventPublishProject(CmsUUID publishHistoryId, I_CmsReport report);
127
128     /**
129      * Scrubs all files from the export folder that might have been changed,
130      * so that the export is newly created after the next request to the resource.<p>
131      *
132      * @param publishHistoryId id of the last published project
133      */

134     public void scrubExportFolders(CmsUUID publishHistoryId) {
135
136         if (LOG.isDebugEnabled()) {
137             LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUBBING_EXPORT_FOLDERS_1, publishHistoryId));
138         }
139
140         Set JavaDoc scrubedFolders = new HashSet JavaDoc();
141         Set JavaDoc scrubedFiles = new HashSet JavaDoc();
142
143         // get a export user cms context
144
CmsObject cms;
145         try {
146             cms = OpenCms.initCmsObject(OpenCms.getDefaultUsers().getUserExport());
147         } catch (CmsException e) {
148             // this should never happen
149
LOG.error(Messages.get().getBundle().key(Messages.LOG_INIT_FAILED_0), e);
150             return;
151         }
152
153         List JavaDoc publishedResources;
154         try {
155             publishedResources = cms.readPublishedResources(publishHistoryId);
156         } catch (CmsException e) {
157
158             LOG.error(
159                 Messages.get().getBundle().key(Messages.LOG_READING_CHANGED_RESOURCES_FAILED_1, publishHistoryId),
160                 e);
161             return;
162         }
163
164         Iterator JavaDoc itPubRes = publishedResources.iterator();
165         while (itPubRes.hasNext()) {
166             CmsPublishedResource res = (CmsPublishedResource)itPubRes.next();
167             if (res.isUnChanged() || !res.isVfsResource()) {
168                 // unchanged resources and non vfs resources don't need to be deleted
169
continue;
170             }
171
172             // ensure all siblings are scrubbed if the resource has one
173
String JavaDoc resPath = cms.getRequestContext().removeSiteRoot(res.getRootPath());
174             List JavaDoc siblings = getSiblingsList(cms, resPath);
175
176             Iterator JavaDoc itSibs = siblings.iterator();
177             while (itSibs.hasNext()) {
178                 String JavaDoc vfsName = (String JavaDoc)itSibs.next();
179
180                 // get the link name for the published file
181
String JavaDoc rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName);
182                 if (LOG.isDebugEnabled()) {
183                     LOG.debug(Messages.get().getBundle().key(Messages.LOG_CHECKING_STATIC_EXPORT_2, vfsName, rfsName));
184                 }
185                 if (rfsName.startsWith(OpenCms.getStaticExportManager().getRfsPrefix(vfsName))
186                     && (!scrubedFiles.contains(rfsName))
187                     && (!scrubedFolders.contains(CmsResource.getFolderPath(rfsName)))) {
188
189                     if (res.isFolder()) {
190                         if (res.isDeleted()) {
191                             String JavaDoc exportFolderName = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getExportPath(
192                                 vfsName)
193                                 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length()));
194                             try {
195                                 File JavaDoc exportFolder = new File JavaDoc(exportFolderName);
196                                 // check if export folder exists, if so delete it
197
if (exportFolder.exists() && exportFolder.canWrite()) {
198                                     CmsFileUtil.purgeDirectory(exportFolder);
199                                     // write log message
200
if (LOG.isInfoEnabled()) {
201                                         LOG.info(Messages.get().getBundle().key(
202                                             Messages.LOG_FOLDER_DELETED_1,
203                                             exportFolderName));
204                                     }
205                                     scrubedFolders.add(rfsName);
206                                     continue;
207                                 }
208                             } catch (Throwable JavaDoc t) {
209                                 // ignore, nothing to do about this
210
if (LOG.isWarnEnabled()) {
211                                     LOG.warn(Messages.get().getBundle().key(
212                                         Messages.LOG_FOLDER_DELETION_FAILED_2,
213                                         vfsName,
214                                         exportFolderName));
215                                 }
216                             }
217                         }
218                         // add index.html to folder name
219
rfsName += CmsStaticExportManager.EXPORT_DEFAULT_FILE;
220                         if (LOG.isDebugEnabled()) {
221                             LOG.debug(Messages.get().getBundle().key(Messages.LOG_FOLDER_1, rfsName));
222                         }
223
224                     }
225
226                     String JavaDoc rfsExportFileName = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getExportPath(
227                         vfsName)
228                         + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length()));
229
230                     purgeFile(rfsExportFileName, vfsName);
231                     scrubedFiles.add(rfsName);
232
233                     List JavaDoc fileList = getRelatedFilesToPurge(rfsExportFileName, vfsName);
234                     Iterator JavaDoc iter = fileList.iterator();
235                     while (iter.hasNext()) {
236                         File JavaDoc file = (File JavaDoc)iter.next();
237                         purgeFile(file.getAbsolutePath(), vfsName);
238                         rfsName = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getRfsPrefix(vfsName)
239                             + "/"
240                             + file.getAbsolutePath().substring(
241                                 OpenCms.getStaticExportManager().getExportPath(vfsName).length()));
242                         rfsName = CmsStringUtil.substitute(rfsName, new String JavaDoc(new char[] {File.separatorChar}), "/");
243                         scrubedFiles.add(rfsName);
244                     }
245                 }
246
247             }
248         }
249     }
250
251     /**
252      * Returns a list of related files to purge.<p>
253      *
254      * @param exportFileName the previous exported rfs filename (already purged)
255      * @param vfsName the vfs name of the resource (to be used to compute more sofisticated sets of related files to purge
256      *
257      * @return a list of related files to purge
258      */

259     protected abstract List JavaDoc getRelatedFilesToPurge(String JavaDoc exportFileName, String JavaDoc vfsName);
260
261     /**
262      * Returns a list containing the root paths of all siblings of a resource.<p>
263      *
264      * @param cms the export user context
265      * @param resPath the path of the resource to get the siblings for
266      * @return a list containing the root paths of all siblings of a resource
267      */

268     protected List JavaDoc getSiblingsList(CmsObject cms, String JavaDoc resPath) {
269
270         List JavaDoc siblings = new ArrayList JavaDoc();
271         try {
272             List JavaDoc li = cms.readSiblings(resPath, CmsResourceFilter.ALL);
273             for (int i = 0, l = li.size(); i < l; i++) {
274                 String JavaDoc vfsName = ((CmsResource)li.get(i)).getRootPath();
275                 siblings.add(vfsName);
276             }
277         } catch (CmsVfsResourceNotFoundException e) {
278             // resource not found, probably because the export user has no read permission on the resource, ignore
279
} catch (CmsSecurityException e) {
280             // security exception, probably because the export user has no read permission on the resource, ignore
281
} catch (CmsException e) {
282             // ignore, nothing to do about this
283
if (LOG.isWarnEnabled()) {
284                 LOG.warn(Messages.get().getBundle().key(Messages.LOG_FETCHING_SIBLINGS_FAILED_1, resPath), e);
285             }
286         }
287         if (!siblings.contains(resPath)) {
288             // always add the resource itself, this has to be done because if the resource was
289
// deleted during publishing, the sibling lookup above will produce no results
290
siblings.add(resPath);
291         }
292         return siblings;
293     }
294
295     /**
296      * Deletes the given file from the RFS if it exists,
297      * also deletes all parameter variations of the file.<p>
298      *
299      * @param rfsFilePath the path of the RFS file to delete
300      * @param vfsName the VFS name of the file to delete (required for logging)
301      */

302     protected void purgeFile(String JavaDoc rfsFilePath, String JavaDoc vfsName) {
303
304         File JavaDoc rfsFile = new File JavaDoc(rfsFilePath);
305
306         // first delete the base file
307
deleteFile(rfsFile, vfsName);
308
309         // now delete the file parameter variations
310
// get the parent folder
311
File JavaDoc parent = rfsFile.getParentFile();
312         if (parent != null) {
313             // list all files in the parent folder that are variations of the base file
314
File JavaDoc[] paramVariants = parent.listFiles(new PrefixFileFilter(rfsFile));
315             if (paramVariants != null) {
316                 for (int v = 0; v < paramVariants.length; v++) {
317                     deleteFile(paramVariants[v], vfsName);
318                 }
319             }
320         }
321     }
322
323     /**
324      * Deletes the given file from the RFS, with error handling and logging.<p>
325      *
326      * @param file the file to delete
327      * @param vfsName the VFS name of the file (required for logging)
328      */

329     private void deleteFile(File JavaDoc file, String JavaDoc vfsName) {
330
331         try {
332             if (file.exists() && file.canWrite()) {
333                 file.delete();
334                 // write log message
335
if (LOG.isInfoEnabled()) {
336                     LOG.info(Messages.get().getBundle().key(Messages.LOG_FILE_DELETED_1, getRfsName(file, vfsName)));
337                 }
338             }
339         } catch (Throwable JavaDoc t) {
340             // ignore, nothing to do about this
341
if (LOG.isWarnEnabled()) {
342                 LOG.warn(
343                     Messages.get().getBundle().key(Messages.LOG_FILE_DELETION_FAILED_1, getRfsName(file, vfsName)),
344                     t);
345             }
346         }
347     }
348
349     /**
350      * Returns the export file name starting from the OpenCms webapp folder.<p>
351      *
352      * @param file the file to delete
353      * @param vfsName the VFS name of the file (required for logging)
354      *
355      * @return the export file name starting from the OpenCms webapp folder
356      */

357     private String JavaDoc getRfsName(File JavaDoc file, String JavaDoc vfsName) {
358
359         String JavaDoc filePath = file.getAbsolutePath();
360         String JavaDoc result = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getRfsPrefix(vfsName)
361             + filePath.substring(OpenCms.getStaticExportManager().getExportPath(vfsName).length()));
362         return CmsStringUtil.substitute(result, new String JavaDoc(new char[] {File.separatorChar}), "/");
363     }
364 }
Popular Tags