001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.importexport;
029
030import org.opencms.configuration.CmsConfigurationException;
031import org.opencms.db.CmsExportPoint;
032import org.opencms.db.CmsExportPointDriver;
033import org.opencms.db.CmsTempFolderExportPointDriver;
034import org.opencms.db.CmsUserExportSettings;
035import org.opencms.db.I_CmsExportPointDriver;
036import org.opencms.file.CmsObject;
037import org.opencms.i18n.CmsMessageContainer;
038import org.opencms.main.CmsEvent;
039import org.opencms.main.CmsException;
040import org.opencms.main.CmsLog;
041import org.opencms.main.I_CmsEventListener;
042import org.opencms.main.OpenCms;
043import org.opencms.report.I_CmsReport;
044import org.opencms.security.CmsRole;
045import org.opencms.security.CmsRoleViolationException;
046import org.opencms.security.I_CmsPrincipal;
047import org.opencms.xml.CmsXmlException;
048
049import java.io.InputStream;
050import java.util.ArrayList;
051import java.util.Collections;
052import java.util.HashMap;
053import java.util.List;
054import java.util.Map;
055import java.util.Set;
056
057import org.apache.commons.logging.Log;
058
059import org.dom4j.Document;
060import org.dom4j.io.SAXReader;
061
062import com.google.common.collect.Lists;
063
064/**
065 * Provides information about how to handle imported resources.<p>
066 *
067 * @since 6.0.0
068 *
069 * @see OpenCms#getImportExportManager()
070 */
071public class CmsImportExportManager {
072
073    /** Time modes to specify how time stamps should be handled. */
074    public static enum TimestampMode {
075    /** Use the timestamp of the imported file. */
076    FILETIME,
077    /** Use the time of import for the timestamp. */
078    IMPORTTIME,
079    /** The timestamp is explicitly given. */
080    VFSTIME;
081
082        /** Returns the default timestamp mode.
083         * @return the default timestamp mode
084         */
085        public static TimestampMode getDefaultTimeStampMode() {
086
087            return VFSTIME;
088        }
089
090        /** More robust version of {@link java.lang.Enum#valueOf(java.lang.Class, String)} that is case insensitive
091         * and defaults for all "unreadable" arguments to the default timestamp mode.
092         * @param value the TimeMode value as String
093         * @return <code>value</code> as TimeMode object, or the default time mode, if <code>value</code> can't be converted to a TimeMode object.
094         */
095        public static TimestampMode getEnum(String value) {
096
097            if (null == value) {
098                return getDefaultTimeStampMode();
099            } else {
100                try {
101                    return TimestampMode.valueOf(value.toUpperCase());
102                } catch (IllegalArgumentException e) {
103                    return getDefaultTimeStampMode();
104                }
105            }
106        }
107    }
108
109    /** Tag in the {@link #EXPORT_MANIFEST} for the "userinfo/entry@name" attribute, contains the additional user info entry name.
110     * @deprecated Use the appropriate tag from latest import class instead*/
111    @Deprecated
112    public static final String A_NAME = A_CmsImport.A_NAME;
113
114    /** Tag in the {@link #EXPORT_MANIFEST} for the "userinfo/entry@type" attribute, contains the additional user info entry data type name.
115     * @deprecated Use the appropriate tag from latest import class instead*/
116    @Deprecated
117    public static final String A_TYPE = A_CmsImport.A_TYPE;
118
119    /** The name of the XML manifest file used for the description of exported OpenCms VFS properties and attributes. */
120    public static final String EXPORT_MANIFEST = "manifest.xml";
121
122    /** The current version of the OpenCms export (appears in the {@link #EXPORT_MANIFEST} header). */
123    public static final String EXPORT_VERSION = "" + CmsImportVersion10.IMPORT_VERSION10; //TODO: when changing this to a newer import version, need to refactor the module updater so it dynamically uses the correct import version
124
125    /**
126     * The name of the XML manifest file used for the description of exported OpenCms VFS properties and attributes.<p>
127     *
128     * @deprecated use {@link #EXPORT_MANIFEST} instead
129     */
130    @Deprecated
131    public static final String EXPORT_XMLFILENAME = EXPORT_MANIFEST;
132
133    /** Tag in the {@link #EXPORT_MANIFEST} for the "access" node.
134     * @deprecated Use the appropriate tag from latest import class instead*/
135    @Deprecated
136    public static final String N_ACCESS = A_CmsImport.N_ACCESS;
137
138    /** Tag in the {@link #EXPORT_MANIFEST} for the "allowed" node, to identify allowed user permissions.
139     * @deprecated Use the appropriate tag from latest import class instead*/
140    @Deprecated
141    public static final String N_ACCESSCONTROL_ALLOWEDPERMISSIONS = A_CmsImport.N_ACCESSCONTROL_ALLOWEDPERMISSIONS;
142
143    /** Tag in the {@link #EXPORT_MANIFEST} for the "denied" node, to identify denied user permissions.
144     * @deprecated Use the appropriate tag from latest import class instead*/
145    @Deprecated
146    public static final String N_ACCESSCONTROL_DENIEDPERMISSIONS = A_CmsImport.N_ACCESSCONTROL_DENIEDPERMISSIONS;
147
148    /** Tag in the {@link #EXPORT_MANIFEST} for the "accesscontrol" node, to identify access control entries.
149     * @deprecated Use the appropriate tag from latest import class instead*/
150    @Deprecated
151    public static final String N_ACCESSCONTROL_ENTRIES = A_CmsImport.N_ACCESSCONTROL_ENTRIES;
152
153    /** Tag in the {@link #EXPORT_MANIFEST} for the "accessentry" node, to identify a single access control entry.
154     * @deprecated Use the appropriate tag from latest import class instead*/
155    @Deprecated
156    public static final String N_ACCESSCONTROL_ENTRY = A_CmsImport.N_ACCESSCONTROL_ENTRY;
157
158    /** Tag in the {@link #EXPORT_MANIFEST} for the "permissionset" node, to identify a permission set.
159     * @deprecated Use the appropriate tag from latest import class instead*/
160    @Deprecated
161    public static final String N_ACCESSCONTROL_PERMISSIONSET = A_CmsImport.N_ACCESSCONTROL_PERMISSIONSET;
162
163    /** Tag in the {@link #EXPORT_MANIFEST} for the "uuidprincipal" node, to identify a principal UUID.
164     * @deprecated Use the appropriate tag from latest import class instead*/
165    @Deprecated
166    public static final String N_ACCESSCONTROL_PRINCIPAL = A_CmsImport.N_ACCESSCONTROL_PRINCIPAL;
167
168    /** Tag for the "creator" node (appears in the {@link #EXPORT_MANIFEST} header). */
169    public static final String N_CREATOR = "creator";
170
171    /** Tag for the "createdate" node (appears in the {@link #EXPORT_MANIFEST} header). */
172    public static final String N_DATE = "createdate";
173
174    /** Tag in the {@link #EXPORT_MANIFEST} for the "datecreated" node, contains the date created VFS file attribute.
175     * @deprecated Use the appropriate tag from latest import class instead*/
176    @Deprecated
177    public static final String N_DATECREATED = A_CmsImport.N_DATECREATED;
178
179    /** Tag in the {@link #EXPORT_MANIFEST} for the "dateexpired" node, contains the expiration date VFS file attribute.
180     * @deprecated Use the appropriate tag from latest import class instead*/
181    @Deprecated
182    public static final String N_DATEEXPIRED = A_CmsImport.N_DATEEXPIRED;
183
184    /** Tag in the {@link #EXPORT_MANIFEST} for the "datelastmodified" node, contains the date last modified VFS file attribute.
185     * @deprecated Use the appropriate tag from latest import class instead*/
186    @Deprecated
187    public static final String N_DATELASTMODIFIED = A_CmsImport.N_DATELASTMODIFIED;
188
189    /** Tag in the {@link #EXPORT_MANIFEST} for the "datereleased" node, contains the release date VFS file attribute.
190     * @deprecated Use the appropriate tag from latest import class instead*/
191    @Deprecated
192    public static final String N_DATERELEASED = A_CmsImport.N_DATERELEASED;
193
194    /** Tag in the {@link #EXPORT_MANIFEST} for the "defaultgroup" node, for backward compatibility with OpenCms 5.x.
195     * @deprecated Use the appropriate tag from latest import class instead*/
196    @Deprecated
197    public static final String N_DEFAULTGROUP = A_CmsImport.N_DEFAULTGROUP;
198
199    /** Tag in the {@link #EXPORT_MANIFEST} for the "description" node, contains a users description test.
200     * @deprecated Use the appropriate tag from latest import class instead*/
201    @Deprecated
202    public static final String N_DESCRIPTION = A_CmsImport.N_DESCRIPTION;
203
204    /** Tag in the {@link #EXPORT_MANIFEST} for the "destination" node, contains target VFS file name.
205     * @deprecated Use the appropriate tag from latest import class instead*/
206    @Deprecated
207    public static final String N_DESTINATION = A_CmsImport.N_DESTINATION;
208
209    /** Tag in the {@link #EXPORT_MANIFEST} for the "email" node, contains a users email.
210     * @deprecated Use the appropriate tag from latest import class instead*/
211    @Deprecated
212    public static final String N_EMAIL = A_CmsImport.N_EMAIL;
213
214    /** Tag in the {@link #EXPORT_MANIFEST} for the "export" node. */
215    public static final String N_EXPORT = "export";
216
217    /** Tag in the {@link #EXPORT_MANIFEST} for the "file" node, container node for all VFS resources.
218     * @deprecated Use the appropriate tag from latest import class instead*/
219    @Deprecated
220    public static final String N_FILE = A_CmsImport.N_FILE;
221
222    /** Tag in the {@link #EXPORT_MANIFEST} for the "firstname" node, contains a users first name.
223     * @deprecated Use the appropriate tag from latest import class instead*/
224    @Deprecated
225    public static final String N_FIRSTNAME = A_CmsImport.N_FIRSTNAME;
226
227    /** Tag in the {@link #EXPORT_MANIFEST} for the "flags" node, contains the flags of a VFS resource.
228     * @deprecated Use the appropriate tag from latest import class instead*/
229    @Deprecated
230    public static final String N_FLAGS = A_CmsImport.N_FLAGS;
231
232    /** Tag in the {@link #EXPORT_MANIFEST} for the "groupdata" node, contains a users group data.
233     * @deprecated Use the appropriate tag from latest import class instead*/
234    @Deprecated
235    public static final String N_GROUPDATA = A_CmsImport.N_GROUPDATA;
236
237    /** Tag in the {@link #EXPORT_MANIFEST} for the "groupname" node, contains a groups name.
238     * @deprecated Use the appropriate tag from latest import class instead*/
239    @Deprecated
240    public static final String N_GROUPNAME = A_CmsImport.N_GROUPNAME;
241
242    /** Tag in the {@link #EXPORT_MANIFEST} for the "id" node, only required for backward compatibility with import version 2.
243     * @deprecated Use the appropriate tag from latest import class instead*/
244    @Deprecated
245    public static final String N_ID = A_CmsImport.N_ID;
246
247    /** Tag in the {@link #EXPORT_MANIFEST}, starts the manifest info header. */
248    public static final String N_INFO = "info";
249
250    /** Tag in the {@link #EXPORT_MANIFEST} for the "infoproject" node, appears in the manifest info header. */
251    public static final String N_INFO_PROJECT = "infoproject";
252
253    /** Tag in the {@link #EXPORT_MANIFEST} for the "lastmodified" node, only required for backward compatibility with import version 2.
254     * @deprecated Use the appropriate tag from latest import class instead*/
255    @Deprecated
256    public static final String N_LASTMODIFIED = A_CmsImport.N_LASTMODIFIED;
257
258    /** Tag in the {@link #EXPORT_MANIFEST} for the "lastname" node, contains a users last name.
259     * @deprecated Use the appropriate tag from latest import class instead*/
260    @Deprecated
261    public static final String N_LASTNAME = A_CmsImport.N_LASTNAME;
262
263    /** Tag in the {@link #EXPORT_MANIFEST} for the "name" node, contains a users login name.
264     * @deprecated Use the appropriate tag from latest import class instead*/
265    @Deprecated
266    public static final String N_NAME = A_CmsImport.N_NAME;
267
268    /** Tag in the {@link #EXPORT_MANIFEST} for the "opencms_version" node, appears in the manifest info header. */
269    public static final String N_OC_VERSION = "opencms_version";
270
271    /** Tag in the {@link #EXPORT_MANIFEST} for the "orgunitdatas" node, starts the organizational unit data.
272     * @deprecated Use the appropriate tag from latest import class instead*/
273    @Deprecated
274    public static final String N_ORGUNITDATA = A_CmsImport.N_ORGUNITDATA;
275
276    /** Tag in the {@link #EXPORT_MANIFEST} for the "parentgroup" node, contains a groups parent group name.
277     * @deprecated Use the appropriate tag from latest import class instead*/
278    @Deprecated
279    public static final String N_PARENTGROUP = A_CmsImport.N_PARENTGROUP;
280
281    /** Tag in the {@link #EXPORT_MANIFEST} for the "password" node, contains a users encrypted password.
282     * @deprecated Use the appropriate tag from latest import class instead*/
283    @Deprecated
284    public static final String N_PASSWORD = A_CmsImport.N_PASSWORD;
285
286    /** Tag in the {@link #EXPORT_MANIFEST} for the "properties" node, starts the list of properties of a VFS resource.
287     * @deprecated Use the appropriate tag from latest import class instead*/
288    @Deprecated
289    public static final String N_PROPERTIES = A_CmsImport.N_PROPERTIES;
290
291    /** Tag in the {@link #EXPORT_MANIFEST} for the "property" node, starts a property for a VFS resource.
292     * @deprecated Use the appropriate tag from latest import class instead*/
293    @Deprecated
294    public static final String N_PROPERTY = A_CmsImport.N_PROPERTY;
295
296    /** Tag in the {@link #EXPORT_MANIFEST} for the "type" property attribute, contains a property type.
297     * @deprecated Use the appropriate tag from latest import class instead*/
298    @Deprecated
299    public static final String N_PROPERTY_ATTRIB_TYPE = A_CmsImport.N_PROPERTY_ATTRIB_TYPE;
300
301    /** Tag in the {@link #EXPORT_MANIFEST} for the "shared" property type attribute value.
302     * @deprecated Use the appropriate tag from latest import class instead*/
303    @Deprecated
304    public static final String N_PROPERTY_ATTRIB_TYPE_SHARED = A_CmsImport.N_PROPERTY_ATTRIB_TYPE_SHARED;
305
306    /** Tag in the {@link #EXPORT_MANIFEST} for the "relation" node, starts a relation for a VFS resource.
307     * @deprecated Use the appropriate tag from latest import class instead*/
308    @Deprecated
309    public static final String N_RELATION = A_CmsImport.N_RELATION;
310
311    /** Tag in the {@link #EXPORT_MANIFEST} for the "id" relation attribute, contains the structure id of the target resource of the relation.
312     * @deprecated Use the appropriate tag from latest import class instead*/
313    @Deprecated
314    public static final String N_RELATION_ATTRIBUTE_ID = A_CmsImport.N_RELATION_ATTRIBUTE_ID;
315
316    /** Tag in the {@link #EXPORT_MANIFEST} for the "path" relation attribute, contains the path to the target resource of the relation.
317     * @deprecated Use the appropriate tag from latest import class instead*/
318    @Deprecated
319    public static final String N_RELATION_ATTRIBUTE_PATH = A_CmsImport.N_RELATION_ATTRIBUTE_PATH;
320
321    /** Tag in the {@link #EXPORT_MANIFEST} for the "type" relation attribute, contains the type of relation.
322     * @deprecated Use the appropriate tag from latest import class instead*/
323    @Deprecated
324    public static final String N_RELATION_ATTRIBUTE_TYPE = A_CmsImport.N_RELATION_ATTRIBUTE_TYPE;
325
326    /** Tag in the {@link #EXPORT_MANIFEST} for the "relations" node, starts the list of relations of a VFS resources.
327     * @deprecated Use the appropriate tag from latest import class instead*/
328    @Deprecated
329    public static final String N_RELATIONS = A_CmsImport.N_RELATIONS;
330
331    /** Tag in the {@link #EXPORT_MANIFEST} for the "source" node, contains the source path of a VFS resource in the import zip (or folder).
332     * @deprecated Use the appropriate tag from latest import class instead*/
333    @Deprecated
334    public static final String N_SOURCE = A_CmsImport.N_SOURCE;
335
336    /** Tag in the {@link #EXPORT_MANIFEST} for the "address" node, contains a users address.
337     * @deprecated Use the appropriate tag from latest import class instead*/
338    @Deprecated
339    public static final String N_TAG_ADDRESS = A_CmsImport.N_TAG_ADDRESS;
340
341    /** Tag in the {@link #EXPORT_MANIFEST} for the "type" node, the resource type name of a VFS resource.
342     * @deprecated Use the appropriate tag from latest import class instead*/
343    @Deprecated
344    public static final String N_TYPE = A_CmsImport.N_TYPE;
345
346    /** Tag in the {@link #EXPORT_MANIFEST} for the "user" node, starts the user data.
347     * @deprecated Use the appropriate tag from latest import class instead*/
348    @Deprecated
349    public static final String N_USER = A_CmsImport.N_USER;
350
351    /** Tag in the {@link #EXPORT_MANIFEST} for the "usercreated" node, contains the name of the user who created the VFS resource.
352     * @deprecated Use the appropriate tag from latest import class instead*/
353    @Deprecated
354    public static final String N_USERCREATED = A_CmsImport.N_USERCREATED;
355
356    /** Tag in the {@link #EXPORT_MANIFEST} for the "userdata" node, starts the list of users.
357     * @deprecated Use the appropriate tag from latest import class instead*/
358    @Deprecated
359    public static final String N_USERDATA = A_CmsImport.N_USERDATA;
360
361    /** Tag in the {@link #EXPORT_MANIFEST} for the "usergroupdatas" node, starts the users group data.
362     * @deprecated Use the appropriate tag from latest import class instead*/
363    @Deprecated
364    public static final String N_USERGROUPDATA = A_CmsImport.N_USERGROUPDATA;
365
366    /** Tag in the {@link #EXPORT_MANIFEST} for the "usergroups" node, starts the users group data.
367     * @deprecated Use the appropriate tag from latest import class instead*/
368    @Deprecated
369    public static final String N_USERGROUPS = A_CmsImport.N_USERGROUPS;
370
371    /** Tag in the {@link #EXPORT_MANIFEST} for the "userinfo" node, contains the additional user info.
372     * @deprecated Use the appropriate tag from latest import class instead*/
373    @Deprecated
374    public static final String N_USERINFO = A_CmsImport.N_USERINFO;
375
376    /** Tag in the {@link #EXPORT_MANIFEST} for the "userinfo/entry" node, contains the additional user info entry value.
377     * @deprecated Use the appropriate tag from latest import class instead*/
378    @Deprecated
379    public static final String N_USERINFO_ENTRY = A_CmsImport.N_USERINFO_ENTRY;
380
381    /** Tag in the {@link #EXPORT_MANIFEST} for the "userlastmodified" node, contains the name of the user who last modified the VFS resource.
382     * @deprecated Use the appropriate tag from latest import class instead*/
383    @Deprecated
384    public static final String N_USERLASTMODIFIED = A_CmsImport.N_USERLASTMODIFIED;
385
386    /** Tag in the {@link #EXPORT_MANIFEST} for the "uuidresource" node, contains a the resource UUID of a VFS resource.
387     * @deprecated Use the appropriate tag from latest import class instead*/
388    @Deprecated
389    public static final String N_UUIDRESOURCE = A_CmsImport.N_UUIDRESOURCE;
390
391    /** Tag in the {@link #EXPORT_MANIFEST} for the "uuidstructure" node, only required for backward compatibility with import version 2.
392     * @deprecated Use the appropriate tag from latest import class instead*/
393    @Deprecated
394    public static final String N_UUIDSTRUCTURE = A_CmsImport.N_UUIDSTRUCTURE;
395
396    /** Tag in the {@link #EXPORT_MANIFEST} for the "value" node, contains the value of a property.
397     * @deprecated Use the appropriate tag from latest import class instead*/
398    @Deprecated
399    public static final String N_VALUE = A_CmsImport.N_VALUE;
400
401    /** Tag in the {@link #EXPORT_MANIFEST} for the "export_version" node, appears in the manifest info header. */
402    public static final String N_VERSION = "export_version";
403
404    /** Property to specify the export time written for a resource's date last modified. */
405    public static final String PROP_EXPORT_TIMESTAMP = "export.timestamp";
406
407    /** The log object for this class. */
408    private static final Log LOG = CmsLog.getLog(CmsImportExportManager.class);
409
410    /** Boolean flag whether imported pages should be converted into XML pages. */
411    private boolean m_convertToXmlPage;
412
413    /** Map from resource types to default timestamp modes. */
414    private Map<String, TimestampMode> m_defaultTimestampModes;
415
416    /** The default values of the HTML->OpenCms Template converter. */
417    private CmsExtendedHtmlImportDefault m_extendedHtmlImportDefault;
418
419    /** List of property keys that should be removed from imported resources. */
420    private List<String> m_ignoredProperties;
421
422    /** List of immutable resources that should remain unchanged when resources are imported. */
423    private List<String> m_immutableResources;
424
425    /** The initialized import/export handlers. */
426    private List<I_CmsImportExportHandler> m_importExportHandlers;
427
428    /** Import principal group translations. */
429    private Map<String, String> m_importGroupTranslations;
430
431    /** Import principal user translations. */
432    private Map<String, String> m_importUserTranslations;
433
434    /** The configured import versions class names. */
435    private List<I_CmsImport> m_importVersionClasses;
436
437    /** Boolean flag whether colliding resources should be overwritten during the import. */
438    private boolean m_overwriteCollidingResources;
439
440    /** List of resourcetypes. Only used as helper for initializing the default timestamp modes. */
441    private List<String> m_resourcetypes;
442
443    /** The configured temporary export point paths. */
444    private List<String> m_tempExportpointPaths = Lists.newArrayList();
445
446    /** The user export settings. */
447    private CmsUserExportSettings m_userExportSettings;
448
449    /** The URL of a 4.x OpenCms application to import content correct into 5.x OpenCms application. */
450    private String m_webAppUrl;
451
452    /**
453     * Creates a new instance for the import/export manager, will be called by the import/export configuration manager.
454     */
455    public CmsImportExportManager() {
456
457        if (LOG.isInfoEnabled()) {
458            LOG.info(Messages.get().getBundle().key(Messages.INIT_IMPORTEXPORT_INITIALIZING_0));
459        }
460
461        m_importExportHandlers = new ArrayList<I_CmsImportExportHandler>();
462        m_immutableResources = new ArrayList<String>();
463        m_ignoredProperties = new ArrayList<String>();
464        m_convertToXmlPage = true;
465        m_importGroupTranslations = new HashMap<String, String>();
466        m_importUserTranslations = new HashMap<String, String>();
467        m_overwriteCollidingResources = true;
468        m_importVersionClasses = new ArrayList<I_CmsImport>();
469        m_defaultTimestampModes = new HashMap<String, TimestampMode>();
470        m_resourcetypes = new ArrayList<String>();
471    }
472
473    /** Adds the provided default timestamp mode for the resourcetypes in list {@link #m_resourcetypes}.
474     * The method is called by the digester.
475     * @param timestampMode the timestamp mode to add as default.
476     */
477    public void addDefaultTimestampMode(String timestampMode) {
478
479        if (null != timestampMode) {
480            try {
481                TimestampMode mode = TimestampMode.valueOf(timestampMode.toUpperCase());
482                for (String resourcetype : m_resourcetypes) {
483                    m_defaultTimestampModes.put(resourcetype, mode);
484
485                    if (LOG.isDebugEnabled()) {
486                        LOG.debug(
487                            Messages.get().getBundle().key(
488                                Messages.LOG_IMPORTEXPORT_EXPORT_SETTIMESTAMPMODE_2,
489                                timestampMode,
490                                resourcetype));
491                    }
492                }
493            } catch (IllegalArgumentException e) {
494                LOG.error(
495                    Messages.get().getBundle().key(
496                        Messages.ERR_IMPORTEXPORT_EXPORT_INVALID_TIMESTAMPMODE_2,
497                        timestampMode,
498                        m_resourcetypes.toString()),
499                    e);
500            }
501        } else {
502            LOG.error(
503                Messages.get().getBundle().key(
504                    Messages.ERR_IMPORTEXPORT_EXPORT_MISSING_TIMESTAMPMODE_1,
505                    m_resourcetypes.toString()));
506        }
507        m_resourcetypes.clear();
508    }
509
510    /**
511     * Adds a property name to the list of properties that should be removed from imported resources.<p>
512     *
513     * @param propertyName a property name
514     */
515    public void addIgnoredProperty(String propertyName) {
516
517        if (LOG.isDebugEnabled()) {
518            LOG.debug(Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_IGNORING_PROPERTY_1, propertyName));
519        }
520        m_ignoredProperties.add(propertyName);
521    }
522
523    /**
524     * Adds a resource to the list of immutable resources that should remain
525     * unchanged when resources are imported.<p>
526     *
527     * @param immutableResource a resources uri in the OpenCms VFS
528     */
529    public void addImmutableResource(String immutableResource) {
530
531        if (LOG.isDebugEnabled()) {
532            LOG.debug(
533                Messages.get().getBundle().key(
534                    Messages.LOG_IMPORTEXPORT_ADDED_IMMUTABLE_RESOURCE_1,
535                    immutableResource));
536        }
537        m_immutableResources.add(immutableResource);
538    }
539
540    /**
541     * Adds an import/export handler to the list of configured handlers.<p>
542     *
543     * @param handler the import/export handler to add
544     */
545    public void addImportExportHandler(I_CmsImportExportHandler handler) {
546
547        if (LOG.isDebugEnabled()) {
548            LOG.debug(Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_ADDED_IMPORTEXPORT_HANDLER_1, handler));
549        }
550        m_importExportHandlers.add(handler);
551    }
552
553    /**
554     * Adds an import princial translation to the configuration.<p>
555     *
556     * @param type the princial type ("USER" or "GROUP")
557     * @param from the "from" translation source
558     * @param to the "to" translation target
559     */
560    public void addImportPrincipalTranslation(String type, String from, String to) {
561
562        if (LOG.isDebugEnabled()) {
563            LOG.debug(
564                Messages.get().getBundle().key(
565                    Messages.LOG_IMPORTEXPORT_ADDED_PRINCIPAL_TRANSLATION_3,
566                    type,
567                    from,
568                    to));
569        }
570        if (I_CmsPrincipal.PRINCIPAL_GROUP.equalsIgnoreCase(type)) {
571            m_importGroupTranslations.put(from, to);
572            if (LOG.isInfoEnabled()) {
573                LOG.info(
574                    Messages.get().getBundle().key(Messages.INIT_IMPORTEXPORT_ADDED_GROUP_TRANSLATION_2, from, to));
575            }
576        } else if (I_CmsPrincipal.PRINCIPAL_USER.equalsIgnoreCase(type)) {
577            m_importUserTranslations.put(from, to);
578            if (LOG.isInfoEnabled()) {
579                LOG.info(Messages.get().getBundle().key(Messages.INIT_IMPORTEXPORT_ADDED_USER_TRANSLATION_2, from, to));
580            }
581        }
582    }
583
584    /**
585     * Adds a import version class name to the configuration.<p>
586     *
587     * @param importVersionClass the import version class name to add
588     */
589    public void addImportVersionClass(I_CmsImport importVersionClass) {
590
591        if (LOG.isDebugEnabled()) {
592            LOG.debug(
593                Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_ADDED_IMPORT_VERSION_1, importVersionClass));
594        }
595        m_importVersionClasses.add(importVersionClass);
596    }
597
598    /** Adds a resourcetype name to the list of resourcetypes that obtain a default timestamp mode in {@link #addDefaultTimestampMode(String)}.
599     * The method is called only by the digester.
600     *
601     * @param resourcetypeName name of the resourcetype
602     */
603    public void addResourceTypeForDefaultTimestampMode(String resourcetypeName) {
604
605        m_resourcetypes.add(resourcetypeName);
606
607    }
608
609    /**
610     * Adds a temporary export point path.<p>
611     *
612     * @param path the new temporary export point path
613     */
614    public void addTempExportpointPath(String path) {
615
616        m_tempExportpointPaths.add(path);
617    }
618
619    /**
620     * Checks if imported pages should be converted into XML pages.<p>
621     *
622     * @return true, if imported pages should be converted into XML pages
623     */
624    public boolean convertToXmlPage() {
625
626        return m_convertToXmlPage;
627    }
628
629    /**
630     * Creates a new export point driver based on the import/export configuration.<p>
631     *
632     * @param exportPoints the export points
633     *
634     * @return the export point driver instance
635     */
636    public I_CmsExportPointDriver createExportPointDriver(Set<CmsExportPoint> exportPoints) {
637
638        if (m_tempExportpointPaths.isEmpty()) {
639            return new CmsExportPointDriver(exportPoints);
640        } else {
641            return new CmsTempFolderExportPointDriver(exportPoints, getTempExportPointPaths());
642        }
643
644    }
645
646    /**
647     * Checks if the current user has permissions to export Cms data of a specified export handler,
648     * and if so, triggers the handler to write the export.<p>
649     *
650     * @param cms the cms context
651     * @param handler handler containing the export data
652     * @param report the output report
653     *
654     * @throws CmsRoleViolationException if the current user is not a allowed to export the OpenCms database
655     * @throws CmsImportExportException if operation was not successful
656     * @throws CmsConfigurationException if something goes wrong
657     *
658     * @see I_CmsImportExportHandler
659     */
660    public void exportData(CmsObject cms, I_CmsImportExportHandler handler, I_CmsReport report)
661    throws CmsConfigurationException, CmsImportExportException, CmsRoleViolationException {
662
663        OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER);
664        handler.exportData(cms, report);
665    }
666
667    /** Returns the default timestamp mode for the resourcetype - or <code>null</code> if no default mode is set.
668     * @param resourcetypeName name of the resourcetype to get the timestamp mode for
669     * @return if set, the default timestamp mode for the resourcetype, otherwise <code>null</code>
670     */
671    public TimestampMode getDefaultTimestampMode(String resourcetypeName) {
672
673        return m_defaultTimestampModes.get(resourcetypeName);
674    }
675
676    /** Returns the map from resourcetype names to default timestamp modes.
677     * @return the map from resourcetype names to default timestamp modes.
678     */
679    public Map<TimestampMode, List<String>> getDefaultTimestampModes() {
680
681        Map<TimestampMode, List<String>> result = new HashMap<TimestampMode, List<String>>();
682        for (String resourcetype : m_defaultTimestampModes.keySet()) {
683            TimestampMode mode = m_defaultTimestampModes.get(resourcetype);
684            if (result.containsKey(mode)) {
685                result.get(mode).add(resourcetype);
686            } else {
687                List<String> list = new ArrayList<String>();
688                list.add(resourcetype);
689                result.put(mode, list);
690            }
691        }
692        return result;
693    }
694
695    /**
696     * Returns the extendedHtmlImportDefault.<p>
697     *
698     * @return the extendedHtmlImportDefault
699     */
700    public CmsExtendedHtmlImportDefault getExtendedHtmlImportDefault() {
701
702        return getExtendedHtmlImportDefault(false);
703    }
704
705    /**
706     * Returns the extendedHtmlImportDefault.<p>
707     *
708     *@param withNull returns the extendenHtmlImport as null if its null,
709     *                otherwise a new CmsExtendedHtmlImportDefault Object is generated
710     *
711     * @return the extendedHtmlImportDefault
712     */
713    public CmsExtendedHtmlImportDefault getExtendedHtmlImportDefault(boolean withNull) {
714
715        return (withNull || (m_extendedHtmlImportDefault != null)
716        ? m_extendedHtmlImportDefault
717        : new CmsExtendedHtmlImportDefault());
718    }
719
720    /**
721     * Returns the list of property keys that should be removed from imported resources.<p>
722     *
723     * @return the list of property keys that should be removed from imported resources, or Collections.EMPTY_LIST
724     */
725    public List<String> getIgnoredProperties() {
726
727        return m_ignoredProperties;
728    }
729
730    /**
731     * Returns the list of immutable resources that should remain unchanged when resources are
732     * imported.<p>
733     *
734     * Certain system resources should not be changed during import. This is the case for the main
735     * folders in the /system/ folder. Changes to these folders usually should not be imported to
736     * another system.<p>
737     *
738     * @return the list of immutable resources, or {@link Collections#EMPTY_LIST}
739     */
740    public List<String> getImmutableResources() {
741
742        return m_immutableResources;
743    }
744
745    /**
746     * Returns an instance of an import/export handler implementation that is able to import
747     * a specified resource.<p>
748     *
749     * @param parameters the import parameters
750     *
751     * @return an instance of an import/export handler implementation
752     *
753     * @throws CmsImportExportException if something goes wrong
754     */
755    @SuppressWarnings("resource")
756    public I_CmsImportExportHandler getImportExportHandler(CmsImportParameters parameters)
757    throws CmsImportExportException {
758
759        Document manifest;
760        InputStream stream = null;
761        CmsImportHelper helper = new CmsImportHelper(parameters);
762        try {
763            helper.openFile();
764            stream = helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
765            SAXReader reader = new SAXReader(false);
766            reader.setValidation(false);
767            reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
768            manifest = reader.read(stream);
769        } catch (Throwable e) {
770            throw new CmsImportExportException(
771                Messages.get().container(Messages.ERR_IMPORTEXPORT_FILE_NOT_FOUND_1, EXPORT_MANIFEST),
772                e);
773        } finally {
774            try {
775                if (stream != null) {
776                    stream.close();
777                }
778            } catch (Exception e) {
779                // noop
780            }
781            helper.closeFile();
782        }
783        for (int i = 0; i < m_importExportHandlers.size(); i++) {
784            I_CmsImportExportHandler handler = m_importExportHandlers.get(i);
785            if (handler.matches(manifest)) {
786                return handler;
787            }
788        }
789
790        CmsMessageContainer message = Messages.get().container(
791            Messages.ERR_IMPORTEXPORT_ERROR_NO_HANDLER_FOUND_1,
792            EXPORT_MANIFEST);
793        if (LOG.isDebugEnabled()) {
794            LOG.debug(message.key());
795        }
796
797        throw new CmsImportExportException(message);
798    }
799
800    /**
801     * Returns the list of configured import/export handlers.<p>
802     *
803     * @return the list of configured import/export handlers
804     */
805    public List<I_CmsImportExportHandler> getImportExportHandlers() {
806
807        return m_importExportHandlers;
808    }
809
810    /**
811     * Returns the configured principal group translations.<p>
812     *
813     * @return the configured principal group translations
814     */
815    public Map<String, String> getImportGroupTranslations() {
816
817        return m_importGroupTranslations;
818    }
819
820    /**
821     * Returns the configured principal user translations.<p>
822     *
823     * @return the configured principal user translations
824     */
825    public Map<String, String> getImportUserTranslations() {
826
827        return m_importUserTranslations;
828    }
829
830    /**
831     * Returns the configured import version class names.<p>
832     *
833     * @return the configured import version class names
834     */
835    public List<I_CmsImport> getImportVersionClasses() {
836
837        return m_importVersionClasses;
838    }
839
840    /**
841     * Returns the URL of a 4.x OpenCms app. (e.g. http://localhost:8080/opencms/opencms/)
842     * from which content was exported.<p>
843     *
844     * This setting is required to import content of 4.x OpenCms apps. correct into 5.x OpenCms apps.<p>
845     *
846     * @return the webAppUrl.
847     */
848    public String getOldWebAppUrl() {
849
850        return m_webAppUrl;
851    }
852
853    /**
854     * Gets the configured list of temporary export point paths.<p>
855     *
856     * If any temporary export point paths are configured, then export points writing to these paths will write to a temporary folder instead.
857     *
858     * @return the list of temporary export point paths
859     */
860    public List<String> getTempExportPointPaths() {
861
862        return Collections.unmodifiableList(m_tempExportpointPaths);
863    }
864
865    /**
866     * Returns the user settings for export.<p>
867     *
868     * @return the user settings for export
869     */
870    public CmsUserExportSettings getUserExportSettings() {
871
872        return m_userExportSettings;
873    }
874
875    /**
876     * Checks if the current user has permissions to import data into the Cms,
877     * and if so, creates a new import handler instance that imports the data.<p>
878     *
879     * @param cms the current OpenCms context object
880     * @param report a Cms report to print log messages
881     * @param parameters the import parameters
882     *
883     * @throws CmsRoleViolationException if the current user is not allowed to import the OpenCms database
884     * @throws CmsImportExportException if operation was not successful
885     * @throws CmsXmlException if the manifest of the import could not be unmarshalled
886     * @throws CmsException in case of errors accessing the VFS
887     *
888     * @see I_CmsImportExportHandler
889     * @see #importData(CmsObject, String, String, I_CmsReport)
890     */
891    public void importData(CmsObject cms, I_CmsReport report, CmsImportParameters parameters)
892    throws CmsImportExportException, CmsXmlException, CmsRoleViolationException, CmsException {
893
894        // check the required role permissions
895        OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER);
896
897        try {
898            OpenCms.fireCmsEvent(
899                new CmsEvent(I_CmsEventListener.EVENT_CLEAR_CACHES, Collections.<String, Object> emptyMap()));
900            I_CmsImportExportHandler handler = getImportExportHandler(parameters);
901            synchronized (handler) {
902                handler.setImportParameters(parameters);
903                handler.importData(cms, report);
904            }
905        } finally {
906            OpenCms.fireCmsEvent(
907                new CmsEvent(I_CmsEventListener.EVENT_CLEAR_CACHES, Collections.<String, Object> emptyMap()));
908        }
909    }
910
911    /**
912     * Checks if the current user has permissions to import data into the Cms,
913     * and if so, creates a new import handler instance that imports the data.<p>
914     *
915     * @param cms the current OpenCms context object
916     * @param importFile the name (absolute path) of the resource (zipfile or folder) to be imported
917     * @param importPath the name (absolute path) of the destination folder in the Cms if required, or null
918     * @param report a Cms report to print log messages
919     *
920     * @throws CmsRoleViolationException if the current user is not allowed to import the OpenCms database
921     * @throws CmsImportExportException if operation was not successful
922     * @throws CmsXmlException if the manifest of the import could not be unmarshalled
923     * @throws CmsException in case of errors accessing the VFS
924     *
925     * @see I_CmsImportExportHandler
926     * @see #importData(CmsObject, I_CmsReport, CmsImportParameters)
927     *
928     * @deprecated use {@link #importData(CmsObject, I_CmsReport, CmsImportParameters)} instead
929     */
930    @Deprecated
931    public void importData(CmsObject cms, String importFile, String importPath, I_CmsReport report)
932    throws CmsImportExportException, CmsXmlException, CmsRoleViolationException, CmsException {
933
934        CmsImportParameters parameters = new CmsImportParameters(importFile, importPath, false);
935        importData(cms, report, parameters);
936    }
937
938    /**
939     * Checks if colliding resources should be overwritten during the import.<p>
940     *
941     * @return true, if colliding resources should be overwritten during the import
942     * @see #setOverwriteCollidingResources(boolean)
943     */
944    public boolean overwriteCollidingResources() {
945
946        return m_overwriteCollidingResources;
947    }
948
949    /**
950     * Sets if imported pages should be converted into XML pages.<p>
951     *
952     * @param convertToXmlPage true, if imported pages should be converted into XML pages.
953     */
954    public void setConvertToXmlPage(boolean convertToXmlPage) {
955
956        if (LOG.isDebugEnabled()) {
957            LOG.debug(
958                Messages.get().getBundle().key(
959                    Messages.LOG_IMPORTEXPORT_SET_CONVERT_PARAMETER_1,
960                    Boolean.toString(convertToXmlPage)));
961        }
962        m_convertToXmlPage = convertToXmlPage;
963    }
964
965    /**
966     * Sets if imported pages should be converted into XML pages.<p>
967     *
968     * @param convertToXmlPage <code>"true"</code>, if imported pages should be converted into XML pages.
969     */
970    public void setConvertToXmlPage(String convertToXmlPage) {
971
972        setConvertToXmlPage(Boolean.valueOf(convertToXmlPage).booleanValue());
973    }
974
975    /**
976     * Sets the extendedHtmlImportDefault.<p>
977     *
978     * @param extendedHtmlImportDefault the extendedHtmlImportDefault to set
979     */
980    public void setExtendedHtmlImportDefault(CmsExtendedHtmlImportDefault extendedHtmlImportDefault) {
981
982        m_extendedHtmlImportDefault = extendedHtmlImportDefault;
983    }
984
985    /**
986     * Sets the URL of a 4.x OpenCms app. (e.g. http://localhost:8080/opencms/opencms/)
987     * from which content was exported.<p>
988     *
989     * This setting is required to import content of 4.x OpenCms apps. correct into 5.x OpenCms apps.<p>
990     *
991     * @param webAppUrl a URL of the a OpenCms app. (e.g. http://localhost:8080/opencms/opencms/)
992     */
993    public void setOldWebAppUrl(String webAppUrl) {
994
995        if (LOG.isDebugEnabled()) {
996            LOG.debug(Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_SET_OLD_WEBAPP_URL_1, webAppUrl));
997        }
998        m_webAppUrl = webAppUrl;
999    }
1000
1001    /**
1002     * Sets whether colliding resources should be overwritten during the import for a
1003     * specified import implementation.<p>
1004     *
1005     * v1 and v2 imports (without resource UUIDs in the manifest) *MUST* overwrite colliding
1006     * resources. Don't forget to set this flag back to it's original value in v1 and v2
1007     * import implementations!<p>
1008     *
1009     * This flag must be set to false to force imports > v2 to move colliding resources to
1010     * /system/lost-found/.<p>
1011     *
1012     * The import implementation has to take care to set this flag correct!<p>
1013     *
1014     * @param overwriteCollidingResources true if colliding resources should be overwritten during the import
1015     */
1016    public void setOverwriteCollidingResources(boolean overwriteCollidingResources) {
1017
1018        if (LOG.isDebugEnabled()) {
1019            LOG.debug(
1020                Messages.get().getBundle().key(
1021                    Messages.LOG_IMPORTEXPORT_SET_OVERWRITE_PARAMETER_1,
1022                    Boolean.toString(overwriteCollidingResources)));
1023        }
1024        m_overwriteCollidingResources = overwriteCollidingResources;
1025    }
1026
1027    /**
1028     * @see CmsImportExportManager#setOverwriteCollidingResources(boolean)
1029     *
1030     * @param overwriteCollidingResources <code>"true"</code> if colliding resources should be overwritten during the import
1031     */
1032    public void setOverwriteCollidingResources(String overwriteCollidingResources) {
1033
1034        setOverwriteCollidingResources(Boolean.valueOf(overwriteCollidingResources).booleanValue());
1035    }
1036
1037    /**
1038     * Sets the user export settings.<p>
1039     *
1040     * @param userExportSettings the user export settings to set
1041     */
1042    public void setUserExportSettings(CmsUserExportSettings userExportSettings) {
1043
1044        m_userExportSettings = userExportSettings;
1045    }
1046
1047    /**
1048     * Returns the translated name for the given group name.<p>
1049     *
1050     * If no matching name is found, the given group name is returned.<p>
1051     *
1052     * @param name the group name to translate
1053     * @return the translated name for the given group name
1054     */
1055    public String translateGroup(String name) {
1056
1057        if (m_importGroupTranslations == null) {
1058            return name;
1059        }
1060        String match = m_importGroupTranslations.get(name);
1061        if (match != null) {
1062            return match;
1063        } else {
1064            return name;
1065        }
1066    }
1067
1068    /**
1069     * Returns the translated name for the given user name.<p>
1070     *
1071     * If no matching name is found, the given user name is returned.<p>
1072     *
1073     * @param name the user name to translate
1074     * @return the translated name for the given user name
1075     */
1076    public String translateUser(String name) {
1077
1078        if (m_importUserTranslations == null) {
1079            return name;
1080        }
1081        String match = m_importUserTranslations.get(name);
1082        if (match != null) {
1083            return match;
1084        } else {
1085            return name;
1086        }
1087    }
1088}