KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > importexport > CmsImport


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/importexport/CmsImport.java,v $
3  * Date : $Date: 2006/03/27 14:52:54 $
4  * Version: $Revision: 1.43 $
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.importexport;
33
34 import org.opencms.file.CmsObject;
35 import org.opencms.file.CmsResource;
36 import org.opencms.file.CmsResourceFilter;
37 import org.opencms.i18n.CmsMessageContainer;
38 import org.opencms.main.CmsEvent;
39 import org.opencms.main.CmsException;
40 import org.opencms.main.CmsLog;
41 import org.opencms.main.I_CmsEventListener;
42 import org.opencms.main.OpenCms;
43 import org.opencms.report.I_CmsReport;
44 import org.opencms.security.CmsRole;
45 import org.opencms.security.CmsRoleViolationException;
46 import org.opencms.util.CmsFileUtil;
47 import org.opencms.xml.CmsXmlException;
48 import org.opencms.xml.CmsXmlUtils;
49
50 import java.io.File JavaDoc;
51 import java.io.FileNotFoundException JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.Collections JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.List JavaDoc;
58 import java.util.zip.ZipEntry JavaDoc;
59 import java.util.zip.ZipFile JavaDoc;
60
61 import org.apache.commons.logging.Log;
62
63 import org.dom4j.Document;
64 import org.dom4j.Element;
65
66 /**
67  * Holds the functionaility to import resources from the filesystem
68  * or a zip file into the OpenCms VFS.<p>
69  *
70  * @author Andreas Zahner
71  * @author Alexander Kandzior
72  * @author Michael Emmerich
73  * @author Thomas Weckert
74  *
75  * @version $Revision: 1.43 $
76  *
77  * @since 6.0.0
78  */

79 public class CmsImport {
80
81     /** The log object for this class. */
82     private static final Log LOG = CmsLog.getLog(CmsImport.class);
83
84     /** The cms context to do the operations with. */
85     protected CmsObject m_cms;
86
87     /** The xml manifest-file. */
88     protected Document m_docXml;
89
90     /** The import-file to load resources from. */
91     protected String JavaDoc m_importFile;
92
93     /** Stores all import interface implementations .*/
94     protected List JavaDoc m_importImplementations;
95
96     /** Indicates if module data is being imported. */
97     protected boolean m_importingChannelData;
98
99     /** The import-path to write resources into the cms. */
100     protected String JavaDoc m_importPath;
101
102     /** The import-resource (folder) to load resources from. */
103     protected File JavaDoc m_importResource;
104
105     /**
106      * The version of this import, noted in the info tag of the manifest.xml.<p>
107      *
108      * 0 indicates an export file without a version number, that is before version 4.3.23 of OpenCms.<br>
109      * 1 indicates an export file of OpenCms with a version before 5.0.0
110      * 2 indicates an export file of OpenCms with a version before 5.1.2
111      * 3 indicates an export file of OpenCms with a version before 5.1.6
112      * 4 indicates an export file of OpenCms with a version after 5.1.6
113      */

114     protected int m_importVersion;
115
116     /** The import-resource (zip) to load resources from. */
117     protected ZipFile JavaDoc m_importZip;
118
119     /** The object to report the log messages. */
120     protected I_CmsReport m_report;
121
122     /**
123      * Constructs a new uninitialized import, required for special subclass data import.<p>
124      */

125     public CmsImport() {
126
127         // empty
128
super();
129     }
130
131     /**
132      * Constructs a new import object which imports the resources from an OpenCms
133      * export zip file or a folder in the "real" file system.<p>
134      *
135      * @param cms the current cms object
136      * @param importFile the file or folder to import from
137      * @param importPath the path in the cms VFS to import into
138      * @param report a report object to output the progress information to
139      *
140      * @throws CmsRoleViolationException if the current user dies not have role permissions to import the database
141      */

142     public CmsImport(CmsObject cms, String JavaDoc importFile, String JavaDoc importPath, I_CmsReport report)
143     throws CmsRoleViolationException {
144
145         // check the role permissions
146
cms.checkRole(CmsRole.IMPORT_DATABASE);
147
148         // set member variables
149
m_cms = cms;
150         m_importFile = importFile;
151         m_importPath = importPath;
152         m_report = report;
153         m_importingChannelData = false;
154         m_importImplementations = OpenCms.getImportExportManager().getImportVersionClasses();
155     }
156
157     /**
158      * Returns the value of a child element with a specified name for a given parent element.<p>
159      *
160      * @param parentElement the parent element
161      * @param elementName the child element name
162      * @return the value of the child node, or null if something went wrong
163      */

164     public static String JavaDoc getChildElementTextValue(Element parentElement, String JavaDoc elementName) {
165
166         try {
167             // get the first child element matching the specified name
168
Element childElement = (Element)parentElement.selectNodes("./" + elementName).get(0);
169             // return the value of the child element
170
return childElement.getTextTrim();
171         } catch (Exception JavaDoc e) {
172             return null;
173         }
174     }
175
176     /**
177      * Returns a list of files which are both in the import and in the virtual file system.<p>
178      *
179      * @return a list of Strings, complete path of the files
180      * @throws CmsImportExportException if the import file could not be opened
181      * @throws CmsXmlException if the manifest of the import could not be unmarshalled
182      */

183     public List JavaDoc getConflictingFilenames() throws CmsXmlException, CmsImportExportException {
184
185         List JavaDoc fileNodes;
186         Element currentElement;
187         String JavaDoc source, destination;
188         List JavaDoc conflictNames = new ArrayList JavaDoc();
189         //String xpathExpr = null;
190

191         if (m_docXml == null) {
192             openImportFile();
193         }
194
195         // get all file-nodes
196
fileNodes = m_docXml.selectNodes("//" + CmsImportExportManager.N_FILE);
197
198         // walk through all files in manifest
199
for (int i = 0; i < fileNodes.size(); i++) {
200             currentElement = (Element)fileNodes.get(i);
201             source = CmsImport.getChildElementTextValue(currentElement, CmsImportExportManager.N_SOURCE);
202             destination = CmsImport.getChildElementTextValue(currentElement, CmsImportExportManager.N_DESTINATION);
203             if (source != null) {
204                 // only consider files
205
boolean exists = true;
206                 try {
207                     CmsResource res = m_cms.readResource(m_importPath + destination);
208                     if (res.getState() == CmsResource.STATE_DELETED) {
209                         exists = false;
210                     }
211                 } catch (CmsException e) {
212                     exists = false;
213                 }
214                 if (exists) {
215                     conflictNames.add(m_importPath + destination);
216                 }
217             }
218         }
219
220         if (m_importZip != null) {
221             try {
222                 m_importZip.close();
223             } catch (IOException JavaDoc e) {
224
225                 CmsMessageContainer message = Messages.get().container(
226                     Messages.ERR_IMPORTEXPORT_ERROR_CLOSING_ZIP_ARCHIVE_1,
227                     m_importZip.getName());
228                 if (LOG.isDebugEnabled()) {
229                     LOG.debug(message.key(), e);
230                 }
231
232                 throw new CmsImportExportException(message, e);
233             }
234         }
235         return conflictNames;
236     }
237
238     /**
239      * Returns a list of resource names that are needed to create a project for this import.<p>
240      *
241      * It calls the method getConflictingFileNames if needed, to calculate these resources.
242      *
243      * @return a list of resource names that are needed to create a project for this import
244      * @throws CmsImportExportException if ZIP archive could not be closed
245      */

246     public List JavaDoc getResourcesForProject() throws CmsImportExportException {
247
248         List JavaDoc fileNodes;
249         Element currentElement;
250         String JavaDoc destination;
251         List JavaDoc resources = new ArrayList JavaDoc();
252
253         try {
254             if (m_importingChannelData) {
255                 m_cms.getRequestContext().saveSiteRoot();
256                 m_cms.getRequestContext().setSiteRoot(CmsResource.VFS_FOLDER_CHANNELS);
257             }
258
259             // get all file-nodes
260
fileNodes = m_docXml.selectNodes("//" + CmsImportExportManager.N_FILE);
261
262             // walk through all files in manifest
263
for (int i = 0; i < fileNodes.size(); i++) {
264                 currentElement = (Element)fileNodes.get(i);
265                 destination = CmsImport.getChildElementTextValue(currentElement, CmsImportExportManager.N_DESTINATION);
266
267                 // get the resources for a project
268
try {
269                     String JavaDoc resource = destination.substring(0, destination.indexOf("/", 1) + 1);
270                     resource = m_importPath + resource;
271                     // add the resource, if it dosen't already exist
272
if ((!resources.contains(resource)) && (!resource.equals(m_importPath))) {
273                         try {
274                             m_cms.readFolder(resource, CmsResourceFilter.IGNORE_EXPIRATION);
275                             // this resource exists in the current project -> add it
276
resources.add(resource);
277                         } catch (CmsException exc) {
278                             // this resource is missing - we need the root-folder
279
resources.add("/");
280                         }
281                     }
282                 } catch (StringIndexOutOfBoundsException JavaDoc exc) {
283                     // this is a resource in root-folder: ignore the excpetion
284
}
285             }
286         } finally {
287             if (m_importingChannelData) {
288                 m_cms.getRequestContext().restoreSiteRoot();
289             }
290         }
291
292         closeImportFile();
293
294         if (resources.contains("/")) {
295             // we have to import root - forget the rest!
296
resources.clear();
297             resources.add("/");
298         }
299
300         return resources;
301     }
302
303     /**
304      * Imports the resources and writes them to the cms VFS, even if there
305      * already exist files with the same name.<p>
306      *
307      * @throws CmsImportExportException if something goes wrong
308      * @throws CmsXmlException if the manifest of the import file could not be unmarshalled
309      */

310     public void importResources() throws CmsImportExportException, CmsXmlException {
311
312         // initialize the import
313
boolean run = false;
314         openImportFile();
315         m_report.println(
316             Messages.get().container(Messages.RPT_IMPORT_VERSION_1, String.valueOf(m_importVersion)),
317             I_CmsReport.FORMAT_NOTE);
318         try {
319             // now find the correct import implementation
320
Iterator JavaDoc i = m_importImplementations.iterator();
321             while (i.hasNext()) {
322                 I_CmsImport imp = (I_CmsImport)i.next();
323                 if (imp.getVersion() == m_importVersion) {
324                     // this is the correct import version, so call it for the import process
325
imp.importResources(
326                         m_cms,
327                         m_importPath,
328                         m_report,
329                         m_importResource,
330                         m_importZip,
331                         m_docXml);
332                     run = true;
333                     break;
334                 }
335             }
336             if (!run) {
337                 m_report.println(
338                     Messages.get().container(Messages.RPT_IMPORT_DB_NO_CLASS_0),
339                     I_CmsReport.FORMAT_WARNING);
340             }
341         } finally {
342             // close the import file
343
closeImportFile();
344             OpenCms.fireCmsEvent(new CmsEvent(I_CmsEventListener.EVENT_CLEAR_OFFLINE_CACHES, Collections.EMPTY_MAP));
345         }
346     }
347
348     /**
349      * Closes the import file.<p>
350      *
351      * @throws CmsImportExportException if the ZIP archive could not be closed
352      */

353     protected void closeImportFile() throws CmsImportExportException {
354
355         if (m_importZip != null) {
356             try {
357                 m_importZip.close();
358             } catch (IOException JavaDoc e) {
359                 m_report.println(e);
360
361                 CmsMessageContainer message = Messages.get().container(
362                     Messages.ERR_IMPORTEXPORT_ERROR_CLOSING_ZIP_ARCHIVE_1,
363                     m_importZip.getName());
364                 if (LOG.isDebugEnabled()) {
365                     LOG.debug(message.key(), e);
366                 }
367
368                 throw new CmsImportExportException(message, e);
369             }
370         }
371     }
372
373     /**
374      * Returns a byte array containing the content of the file.<p>
375      *
376      * @param filename the name of the file to read
377      * @return a byte array containing the content of the file
378      */

379     protected byte[] getFileBytes(String JavaDoc filename) {
380
381         try {
382             // is this a zip-file?
383
if (m_importZip != null) {
384                 // yes
385
ZipEntry JavaDoc entry = m_importZip.getEntry(filename);
386                 InputStream JavaDoc stream = m_importZip.getInputStream(entry);
387                 int size = new Long JavaDoc(entry.getSize()).intValue();
388                 return CmsFileUtil.readFully(stream, size);
389             } else {
390                 // no - use directory
391
File JavaDoc file = new File JavaDoc(m_importResource, filename);
392                 return CmsFileUtil.readFile(file);
393             }
394         } catch (FileNotFoundException JavaDoc fnfe) {
395             m_report.println(fnfe);
396         } catch (IOException JavaDoc ioe) {
397             m_report.println(ioe);
398         }
399         // this will only be returned in case there was an exception
400
return "".getBytes();
401     }
402
403     /**
404      * Gets the import resource and stores it in object-member.<p>
405      *
406      * @throws CmsImportExportException if the import file could not be opened
407      */

408     protected void getImportResource() throws CmsImportExportException {
409
410         try {
411             // get the import resource
412
m_importResource = new File JavaDoc(OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(m_importFile));
413
414             // if it is a file it must be a zip-file
415
if (m_importResource.isFile()) {
416                 m_importZip = new ZipFile JavaDoc(m_importResource);
417             }
418         } catch (IOException JavaDoc e) {
419             m_report.println(e);
420
421             CmsMessageContainer message = Messages.get().container(
422                 Messages.ERR_IMPORTEXPORT_ERROR_OPENING_ZIP_ARCHIVE_1,
423                 m_importFile);
424             if (LOG.isDebugEnabled()) {
425                 LOG.debug(message.key(), e);
426             }
427
428             throw new CmsImportExportException(message, e);
429         }
430     }
431
432     /**
433      * Initalizes the import.<p>
434      *
435      * @throws CmsImportExportException if the import file could not be opened
436      * @throws CmsXmlException if the manifest of the import could not be unmarshalled
437      */

438     protected void openImportFile() throws CmsXmlException, CmsImportExportException {
439
440         // open the import resource
441
getImportResource();
442
443         // read the xml-config file
444
m_docXml = CmsXmlUtils.unmarshalHelper(getFileBytes(CmsImportExportManager.EXPORT_MANIFEST), null);
445
446         // try to read the export version number
447
try {
448             m_importVersion = Integer.parseInt(((Element)m_docXml.selectNodes("//" + CmsImportExportManager.N_VERSION).get(
449                 0)).getTextTrim());
450         } catch (Exception JavaDoc e) {
451             //ignore the exception, the export file has no version nummber (version 0).
452
}
453     }
454 }
Popular Tags