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.CmsConfigurationManager;
031import org.opencms.configuration.CmsParameterConfiguration;
032import org.opencms.db.CmsDbEntryNotFoundException;
033import org.opencms.db.log.CmsLogEntry;
034import org.opencms.file.CmsDataAccessException;
035import org.opencms.file.CmsFile;
036import org.opencms.file.CmsObject;
037import org.opencms.file.CmsProject;
038import org.opencms.file.CmsProperty;
039import org.opencms.file.CmsPropertyDefinition;
040import org.opencms.file.CmsRequestContext;
041import org.opencms.file.CmsResource;
042import org.opencms.file.CmsResourceBuilder;
043import org.opencms.file.CmsResourceFilter;
044import org.opencms.file.CmsUser;
045import org.opencms.file.CmsVfsResourceNotFoundException;
046import org.opencms.file.types.CmsResourceTypeFolder;
047import org.opencms.file.types.CmsResourceTypePlain;
048import org.opencms.file.types.CmsResourceTypeXmlAdeConfiguration;
049import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
050import org.opencms.file.types.I_CmsResourceType;
051import org.opencms.i18n.CmsMessageContainer;
052import org.opencms.importexport.CmsImportExportManager.TimestampMode;
053import org.opencms.loader.CmsLoaderException;
054import org.opencms.lock.CmsLock;
055import org.opencms.main.CmsException;
056import org.opencms.main.CmsIllegalStateException;
057import org.opencms.main.CmsLog;
058import org.opencms.main.OpenCms;
059import org.opencms.relations.CmsRelationType;
060import org.opencms.relations.I_CmsLinkParseable;
061import org.opencms.report.I_CmsReport;
062import org.opencms.security.CmsAccessControlEntry;
063import org.opencms.security.CmsOrganizationalUnit;
064import org.opencms.security.CmsRole;
065import org.opencms.security.I_CmsPasswordHandler;
066import org.opencms.security.I_CmsPrincipal;
067import org.opencms.ui.apps.lists.CmsListManager;
068import org.opencms.util.CmsCollectionsGenericWrapper;
069import org.opencms.util.CmsDataTypeUtil;
070import org.opencms.util.CmsDateUtil;
071import org.opencms.util.CmsMacroResolver;
072import org.opencms.util.CmsStringUtil;
073import org.opencms.util.CmsUUID;
074import org.opencms.xml.CmsXmlEntityResolver;
075import org.opencms.xml.CmsXmlErrorHandler;
076import org.opencms.xml.content.CmsXmlContent;
077
078import java.io.File;
079import java.io.IOException;
080import java.io.InputStream;
081import java.text.ParseException;
082import java.util.ArrayList;
083import java.util.Arrays;
084import java.util.Collection;
085import java.util.Collections;
086import java.util.HashMap;
087import java.util.HashSet;
088import java.util.Iterator;
089import java.util.List;
090import java.util.Map;
091import java.util.Map.Entry;
092import java.util.Set;
093import java.util.concurrent.atomic.AtomicLong;
094import java.util.zip.ZipFile;
095
096import org.apache.commons.codec.binary.Base64;
097import org.apache.commons.digester3.Digester;
098import org.apache.commons.digester3.Rule;
099import org.apache.commons.logging.Log;
100
101import org.dom4j.Document;
102import org.xml.sax.Attributes;
103import org.xml.sax.SAXException;
104
105import com.google.common.base.Objects;
106import com.google.common.collect.ArrayListMultimap;
107import com.google.common.collect.Multimap;
108
109/**
110 * Adds the XML handler rules for import and export of resources and accounts.<p>
111 *
112 * @since 7.0.4
113 */
114public class CmsImportVersion10 implements I_CmsImport {
115
116    /**
117     * Categories of resources that need to be handled differently in the 'rewrite parseables' import step.
118     */
119    public static enum LinkParsableCategory {
120        /** ADE config (formatters, sitemap configs) */
121        config,
122
123        /** Container pages. */
124        page,
125
126        /** Other contents. */
127        other;
128    }
129
130    /**
131     * Data class to temporarily keep track of relation data for a resource to be imported.<p>
132     */
133    public static class RelationData {
134
135        /** The relation target. */
136        private String m_target;
137
138        /** The target structure id. */
139        private CmsUUID m_targetId;
140
141        /** The relation type. */
142        private CmsRelationType m_type;
143
144        /**
145         * Creates a new instance.<p>
146         *
147         * @param target the relation target path
148         * @param targetId the relation target structure id
149         * @param type the relation type
150         */
151        public RelationData(String target, CmsUUID targetId, CmsRelationType type) {
152
153            super();
154            m_target = target;
155            m_type = type;
156            m_targetId = targetId;
157        }
158
159        /**
160         * @see java.lang.Object#equals(java.lang.Object)
161         */
162        @Override
163        public boolean equals(Object otherObj) {
164
165            if (!(otherObj instanceof RelationData)) {
166                return false;
167            }
168            RelationData other = (RelationData)otherObj;
169            return Objects.equal(m_target, other.m_target)
170                && Objects.equal(m_type, other.m_type)
171                && Objects.equal(m_targetId, other.m_targetId);
172        }
173
174        /**
175         * Gets the relation target path.<p>
176         *
177         * @return the relation target path
178         */
179        public String getTarget() {
180
181            return m_target;
182        }
183
184        /**
185         * Gets the relation target structure id.<p>
186         *
187         * @return the relation target structure id
188         */
189        public CmsUUID getTargetId() {
190
191            return m_targetId;
192        }
193
194        /**
195         * Gets the relation type.<p>
196         *
197         * @return the relation type
198         */
199        public CmsRelationType getType() {
200
201            return m_type;
202        }
203
204        /**
205         * @see java.lang.Object#hashCode()
206         */
207        @Override
208        public int hashCode() {
209
210            return Objects.hashCode(m_target, m_type.getName(), m_targetId);
211
212        }
213
214    }
215
216    /** Tag for the "userinfo / entry name" attribute, contains the additional user info entry name. */
217    public static final String A_NAME = "name";
218
219    /** Tag for the "type" attribute, contains the property type. */
220    public static final String A_TYPE = "type";
221
222    /** The name of the DTD for this import version. */
223    public static final String DTD_FILENAME = "opencms-import10.dtd";
224
225    /** The location of the OpenCms configuration DTD if the default prefix is the system ID. */
226    public static final String DTD_LOCATION = "org/opencms/importexport/";
227
228    /** The version number of this import implementation.<p> */
229    public static final int IMPORT_VERSION10 = 10;
230
231    /** Tag for the "allowed" node, to identify allowed user permissions. */
232    public static final String N_ACCESSCONTROL_ALLOWEDPERMISSIONS = "allowed";
233
234    /** Tag for the "denied" node, to identify denied user permissions. */
235    public static final String N_ACCESSCONTROL_DENIEDPERMISSIONS = "denied";
236
237    /** Tag for the "accesscontrol" node, to identify access control entries. */
238    public static final String N_ACCESSCONTROL_ENTRIES = "accesscontrol";
239
240    /** Tag for the "accessentry" node, to identify a single access control entry. */
241    public static final String N_ACCESSCONTROL_ENTRY = "accessentry";
242
243    /** Tag for the "permissionset" node, to identify a permission set. */
244    public static final String N_ACCESSCONTROL_PERMISSIONSET = "permissionset";
245
246    /** Tag for the "uuidprincipal" node, to identify a principal UUID. */
247    public static final String N_ACCESSCONTROL_PRINCIPAL = "uuidprincipal";
248
249    /** Tag for the "accounts" node. */
250    public static final String N_ACCOUNTS = "accounts";
251
252    /** Tag for the "datecreated" node, contains the date created VFS file attribute. */
253    public static final String N_DATECREATED = "datecreated";
254
255    /** Tag for the "dateexpired" node, contains the expiration date VFS file attribute. */
256    public static final String N_DATEEXPIRED = "dateexpired";
257
258    /** Tag for the "datelastmodified" node, contains the date last modified VFS file attribute. */
259    public static final String N_DATELASTMODIFIED = "datelastmodified";
260
261    /** Tag for the "datereleased" node, contains the release date VFS file attribute. */
262    public static final String N_DATERELEASED = "datereleased";
263
264    /** Tag for the "description" node, contains a users description test. */
265    public static final String N_DESCRIPTION = "description";
266
267    /** Tag for the "destination" node, contains target VFS file name. */
268    public static final String N_DESTINATION = "destination";
269
270    /** Tag for the "email" node, contains a users email. */
271    public static final String N_EMAIL = "email";
272
273    /** Tag for the "file" node, container node for all VFS resources. */
274    public static final String N_FILE = "file";
275
276    /** Tag for the "files" node, container node for all VFS resources. */
277    public static final String N_FILES = "files";
278
279    /** Tag for the "firstname" node, contains a users first name. */
280    public static final String N_FIRSTNAME = "firstname";
281
282    /** Tag for the "flags" node, contains the flags of a VFS resource. */
283    public static final String N_FLAGS = "flags";
284
285    /** Tag for the "group" node, contains a group name. */
286    public static final String N_GROUP = "group";
287
288    /** Tag for the "groups" node, contains a users group data. */
289    public static final String N_GROUPS = "groups";
290
291    /** Tag for the "id" relation attribute, contains the structure id of the target resource of the relation. */
292    public static final String N_ID = "id";
293
294    /** Tag for the "lastname" node, contains a users last name. */
295    public static final String N_LASTNAME = "lastname";
296
297    /** Tag for the "managersgroup" node, contains name of the managers group of the project. */
298    public static final String N_MANAGERSGROUP = "managersgroup";
299
300    /** Tag for the "name" node, contains the name of a property. */
301    public static final String N_NAME = "name";
302
303    /** Tag for the "orgunit" node, starts the organizational unit data. */
304    public static final String N_ORGUNIT = "orgunit";
305
306    /** Tag for the "orgunits" node, starts the organizational unit data. */
307    public static final String N_ORGUNITS = "orgunits";
308
309    /** Tag for the "parentgroup" node, contains a groups parent group fqn. */
310    public static final String N_PARENTGROUP = "parentgroup";
311
312    /** Tag for the "password" node, contains a users encrypted password. */
313    public static final String N_PASSWORD = "password";
314
315    /** Tag for the "path" relation attribute, contains the path to the target resource of the relation. */
316    public static final String N_PATH = "path";
317
318    /** Tag for the "project" node, starts the project data. */
319    public static final String N_PROJECT = "project";
320
321    /** Tag for the "projects" node, starts the project data. */
322    public static final String N_PROJECTS = "projects";
323
324    /** Tag for the "properties" node, starts the list of properties of a VFS resource. */
325    public static final String N_PROPERTIES = "properties";
326
327    /** Tag for the "property" node, starts a property for a VFS resource. */
328    public static final String N_PROPERTY = "property";
329
330    /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "relation" node, starts a relation for a VFS resource. */
331    public static final String N_RELATION = "relation";
332
333    /** Tag for the "relations" node, starts the list of relations of a VFS resources. */
334    public static final String N_RELATIONS = "relations";
335
336    /** Tag for the "resource" node, contains the a organizational unit resource name. */
337    public static final String N_RESOURCE = "resource";
338
339    /** Tag for the "resources" node, contains the list of organizational unit resources. */
340    public static final String N_RESOURCES = "resources";
341
342    /** Tag for the "source" node, contains the source path of a VFS resource in the import zip (or folder). */
343    public static final String N_SOURCE = "source";
344
345    /** Tag for the "type" node, the resource type name of a VFS resource. */
346    public static final String N_TYPE = "type";
347
348    /** Tag for the "user" node, starts the user data. */
349    public static final String N_USER = "user";
350
351    /** Tag for the "usercreated" node, contains the name of the user who created the VFS resource. */
352    public static final String N_USERCREATED = "usercreated";
353
354    /** Tag for the "usergroup" node, the name of a users group. */
355    public static final String N_USERGROUP = "usergroup";
356
357    /** Tag for the "usergroups" node, starts the users group data. */
358    public static final String N_USERGROUPS = "usergroups";
359
360    /** Tag for the "userinfo" node, contains the additional user info. */
361    public static final String N_USERINFO = "userinfo";
362
363    /** Tag for the "userinfo/entry" node, contains the additional user info entry value. */
364    public static final String N_USERINFO_ENTRY = "entry";
365
366    /** Tag for the "userlastmodified" node, contains the name of the user who last modified the VFS resource. */
367    public static final String N_USERLASTMODIFIED = "userlastmodified";
368
369    /** Tag for the "userrole" node, contains an users role name. */
370    public static final String N_USERROLE = "userrole";
371
372    /** Tag for the "userroles" node, starts the users role data. */
373    public static final String N_USERROLES = "userroles";
374
375    /** Tag for the "users" node, starts the list of users. */
376    public static final String N_USERS = "users";
377
378    /** Tag for the "usersgroup" node, contains name of the users group of the project. */
379    public static final String N_USERSGROUP = "usersgroup";
380
381    /** Tag for the "uuidresource" node, contains a the resource UUID of a VFS resource. */
382    public static final String N_UUIDRESOURCE = "uuidresource";
383
384    /** Tag for the "uuidstructure" node, only required for backward compatibility with import version 2. */
385    public static final String N_UUIDSTRUCTURE = "uuidstructure";
386
387    /** Tag for the "value" node, contains the value of a property. */
388    public static final String N_VALUE = "value";
389
390    /** Value for the "shared" property type attribute value. */
391    public static final String PROPERTY_ATTRIB_TYPE_SHARED = "shared";
392
393    /** Constant for the unspecified creation date. */
394    protected static final long DATE_CREATED_UNSPECIFIED = -1;
395
396    /** Constant for using file time as last modification date on file import. */
397    protected static final long DATE_LAST_MODIFICATION_FILETIME = -1;
398
399    /** Constant for an unspecified last modification date. */
400    protected static final long DATE_LAST_MODIFICATION_UNSPECIFIED = -2;
401
402    /** The log object for this class. */
403    private static final Log LOG = CmsLog.getLog(CmsImportVersion10.class);
404
405    /** Cumulative time spent waiting for config updates. */
406    private static final AtomicLong cumulativeConfigWaitTime = new AtomicLong(0l);
407
408    /** The ACE flags value. */
409    protected int m_aceFlags;
410
411    /** The ACE allowed permissions value. */
412    protected int m_acePermissionsAllowed;
413
414    /** The ACE denied permissions value. */
415    protected int m_acePermissionsDenied;
416
417    /** The ACE principal id value. */
418    protected CmsUUID m_acePrincipalId;
419
420    /** The list of ACEs for the current imported resource. */
421    protected List<CmsAccessControlEntry> m_aces;
422
423    /** The cms object. */
424    protected CmsObject m_cms;
425
426    /** The set of resource ids of files which actually are contained in the zip file. */
427    protected Set<CmsUUID> m_contentFiles = new HashSet<CmsUUID>();
428
429    /** The destination value. */
430    protected String m_destination;
431
432    /** The current file counter. */
433    protected int m_fileCounter;
434
435    /** The description of the current group to import. */
436    protected String m_groupDescription;
437
438    /** The flags of the current group to import. */
439    protected int m_groupFlags;
440
441    /** The name of the current group to import. */
442    protected String m_groupName;
443
444    /** The parent of the current group to import. */
445    protected String m_groupParent;
446
447    /** Map of all parent groups that could not be set immediately, because of the import order. */
448    protected Map<String, List<String>> m_groupParents;
449
450    /** True if a modification date has been set. */
451    protected boolean m_hasDateLastModified;
452
453    /** True if a structure id has been set. */
454    protected boolean m_hasStructureId;
455
456    /** The import helper. */
457    protected CmsImportHelper m_helper;
458
459    /** List of ignored properties. */
460    protected List<String> m_ignoredProperties;
461
462    /** List of immutable resources. */
463    protected List<String> m_immutables;
464
465    /** The flag to import ACEs. */
466    protected boolean m_importACEs;
467
468    /** The membership structure. */
469    protected Map<String, Map<String, Map<String, String>>> m_membership;
470
471    /** The current imported organizational unit. */
472    protected CmsOrganizationalUnit m_orgUnit;
473
474    /** The organizational unit description. */
475    protected String m_orgUnitDescription;
476
477    /** The organizational unit flags. */
478    protected int m_orgUnitFlags;
479
480    /** The organizational unit fqn. */
481    protected String m_orgUnitName;
482
483    /** The map of organizational unit resources, this is a global field that will be use at the end of the import. */
484    protected Map<String, List<String>> m_orgUnitResources;
485
486    /** The import parameters to use. */
487    protected CmsImportParameters m_parameters;
488
489    /** The list of resource to be parsed, this is a global list, which will be handled at the end of the import. */
490    protected List<CmsResource> m_parseables;
491
492    /** The project description. */
493    protected String m_projectDescription;
494
495    /** The project managers group name. */
496    protected String m_projectManagers;
497
498    /** The project fqn. */
499    protected String m_projectName;
500
501    /** The current read project resources. */
502    protected List<String> m_projectResources;
503
504    /** The project users group name. */
505    protected String m_projectUsers;
506
507    /** The map of properties for current imported resource. */
508    protected Map<String, CmsProperty> m_properties;
509
510    /** The property name value. */
511    protected String m_propertyName;
512
513    /** The property value value. */
514    protected String m_propertyValue;
515
516    /** The relation id value. */
517    protected CmsUUID m_relationId;
518
519    /** The relation path value. */
520    protected String m_relationPath;
521
522    /** Holds the relation data for the resource to be imported. */
523    protected List<RelationData> m_relationsForResource;
524
525    /** The relation type value. */
526    protected CmsRelationType m_relationType;
527
528    /** The report. */
529    protected I_CmsReport m_report;
530
531    /** The current imported resource. */
532    protected CmsResource m_resource;
533
534    /** Holds the field values for the CmsResource object to be created. */
535    protected CmsResourceBuilder m_resourceBuilder;
536
537    /** The source value. */
538    protected String m_source;
539
540    /** Possible exception during xml parsing. */
541    protected Throwable m_throwable;
542
543    /** The total number of files to import. */
544    protected int m_totalFiles;
545
546    /** The type name. */
547    protected String m_typeName;
548
549    /** The current imported user. */
550    protected CmsUser m_user;
551
552    /** The current user date created. */
553    protected long m_userDateCreated;
554
555    /** The current user email. */
556    protected String m_userEmail;
557
558    /** The current user first name. */
559    protected String m_userFirstname;
560
561    /** The current user flags. */
562    protected int m_userFlags;
563
564    /** The additional information for the current imported user. */
565    protected Map<String, Object> m_userInfos;
566
567    /** The current user last name. */
568    protected String m_userLastname;
569
570    /** The current user name. */
571    protected String m_userName;
572
573    /** The current user password. */
574    protected String m_userPassword;
575
576    /** The export version. */
577    protected int m_version;
578
579    /**
580     * Maps index of files in import to structure ids of imported resources.
581     * Necessary because not all entries in the manifest may have a structure id, and even for entries
582     * with a structure id, there may be a pre-existing resource at the same path with a different structure id.
583     */
584    private Map<Integer, CmsUUID> m_indexToStructureId;
585
586    /** Map to keep track of relation data for resources to be imported. */
587    private Multimap<Integer, RelationData> m_relationData;
588
589    /** True if the resource id has not been set. */
590    private boolean m_resourceIdWasNull;
591
592    /** Flag which indicates whether the resource type name from the manifest was not found. */
593    private boolean m_unknownType;
594
595    /**
596     * Public constructor.<p>
597     */
598    public CmsImportVersion10() {
599
600        // empty
601    }
602
603    /**
604     * Parses the links.<p>
605     *
606     * @param cms the CMS context to use
607     * @param parseables the list of resources for which to parse the links
608     * @param report the report
609     */
610    public static void parseLinks(CmsObject cms, List<CmsResource> parseables, I_CmsReport report) {
611
612        int i = 0;
613
614        // group parseables into categories that need to be handled differently.
615        //
616        //  - container pages need to be rewritten before contents (because the contents' gallery titles
617        //    may reference the container page they're in)
618        //
619        // - configurations need to be rewritten *and* loaded before container pages
620        //   (because how the container page is written may depend on a sitemap configuration
621        //   in the same import).
622
623        ArrayListMultimap<LinkParsableCategory, CmsResource> resourcesByCategory = ArrayListMultimap.create();
624        for (CmsResource resource : parseables) {
625            LinkParsableCategory category = LinkParsableCategory.other;
626            if (CmsResourceTypeXmlContainerPage.isContainerPage(resource)) {
627                category = LinkParsableCategory.page;
628            } else {
629                I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(resource);
630                if ((resType instanceof CmsResourceTypeXmlAdeConfiguration)
631                    && !OpenCms.getResourceManager().matchResourceType(
632                        CmsListManager.RES_TYPE_LIST_CONFIG,
633                        resource.getTypeId())) {
634                    category = LinkParsableCategory.config;
635                }
636            }
637            resourcesByCategory.put(category, resource);
638        }
639
640        for (LinkParsableCategory category : Arrays.asList(
641            LinkParsableCategory.config,
642            LinkParsableCategory.page,
643            LinkParsableCategory.other)) {
644
645            List<CmsResource> resourcesInCurrentCategory = resourcesByCategory.get(category);
646            resourcesInCurrentCategory.sort((a, b) -> a.getRootPath().compareTo(b.getRootPath()));
647            for (CmsResource parsableRes : resourcesInCurrentCategory) {
648                String resName = cms.getSitePath(parsableRes);
649
650                report.print(
651                    org.opencms.report.Messages.get().container(
652                        org.opencms.report.Messages.RPT_SUCCESSION_2,
653                        String.valueOf(i + 1),
654                        String.valueOf(parseables.size())),
655                    I_CmsReport.FORMAT_NOTE);
656
657                LOG.info("Rewriting parsable resource: " + resName);
658                report.print(
659                    Messages.get().container(Messages.RPT_PARSE_LINKS_FOR_1, resName),
660                    I_CmsReport.FORMAT_NOTE);
661                report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
662
663                try {
664                    CmsFile file = cms.readFile(resName);
665                    // make sure the date last modified is kept...
666                    file.setDateLastModified(file.getDateLastModified());
667                    // make sure the file is locked
668                    CmsLock lock = cms.getLock(file);
669                    if (lock.isUnlocked()) {
670                        cms.lockResource(resName);
671                    } else if (!lock.isDirectlyOwnedInProjectBy(cms)) {
672                        cms.changeLock(resName);
673                    }
674                    // rewrite the file
675                    cms.getRequestContext().setAttribute(CmsXmlContent.AUTO_CORRECTION_ATTRIBUTE, Boolean.TRUE);
676                    try {
677                        cms.writeFile(file);
678                    } finally {
679                        cms.getRequestContext().removeAttribute(CmsXmlContent.AUTO_CORRECTION_ATTRIBUTE);
680                    }
681
682                    report.println(
683                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
684                        I_CmsReport.FORMAT_OK);
685                } catch (Throwable e) {
686                    report.addWarning(e);
687                    report.println(
688                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0),
689                        I_CmsReport.FORMAT_ERROR);
690                    if (LOG.isWarnEnabled()) {
691                        LOG.warn(Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_REWRITING_1, resName));
692                        LOG.warn(e.getMessage(), e);
693                    }
694                    if (LOG.isDebugEnabled()) {
695                        LOG.debug(e.getLocalizedMessage(), e);
696                    }
697                }
698                i++;
699            }
700            if ((category == LinkParsableCategory.config) && (resourcesInCurrentCategory.size() > 0)) {
701                long start = System.currentTimeMillis();
702                OpenCms.getADEManager().waitForFormatterCache(false);
703                OpenCms.getADEManager().waitForCacheUpdate(false);
704                long end = System.currentTimeMillis();
705                long waitTime = end - start;
706                long cumulative = cumulativeConfigWaitTime.addAndGet(waitTime);
707                LOG.debug("Waited " + (waitTime / 1000.0) + "s for configuration in parseLinks, total = " + cumulative);
708
709            }
710        }
711        cms.getRequestContext().removeAttribute(CmsLogEntry.ATTR_LOG_ENTRY);
712    }
713
714    /**
715     * Adds an ACE from the current xml data.<p>
716     *
717     * @see #addResourceAceRules(Digester, String)
718     */
719    public void addAccessControlEntry() {
720
721        try {
722            if (m_throwable != null) {
723                // user or group of ACE might not exist in target system, ignore ACE
724                if (LOG.isWarnEnabled()) {
725                    LOG.warn(
726                        Messages.get().getBundle().key(
727                            Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_ACE_1,
728                            getRequestContext().removeSiteRoot(m_resource.getRootPath())),
729                        m_throwable);
730                }
731                getReport().println(m_throwable);
732                getReport().addError(m_throwable);
733                m_throwable = null;
734                return;
735            }
736            if (m_aces == null) {
737                // this list will be used and clean up in the importResource and importAccessControlEntries methods
738                m_aces = new ArrayList<CmsAccessControlEntry>();
739            }
740            m_aces.add(
741                new CmsAccessControlEntry(
742                    null,
743                    m_acePrincipalId,
744                    m_acePermissionsAllowed,
745                    m_acePermissionsDenied,
746                    m_aceFlags));
747        } finally {
748            m_acePrincipalId = null;
749            m_acePermissionsAllowed = 0;
750            m_acePermissionsDenied = 0;
751            m_aceFlags = 0;
752        }
753    }
754
755    /**
756     * Registers a file whose contents are contained in the zip file.<p>
757     *
758     * @param source the path in the zip file
759     *
760     * @param resourceId the resource id
761     */
762    public void addContentFile(String source, String resourceId) {
763
764        if ((source != null) && (resourceId != null)) {
765            try {
766                m_helper.getFileBytes(source);
767                m_contentFiles.add(new CmsUUID(resourceId));
768            } catch (@SuppressWarnings("unused") CmsImportExportException e) {
769                LOG.info("File not found in import: " + source);
770            }
771        }
772    }
773
774    /**
775     * Adds a new resource to be associated to the current organizational unit.<p>
776     *
777     * @param resourceName the resource name to add
778     */
779    public void addOrgUnitResource(String resourceName) {
780
781        if ((m_throwable != null) || (m_orgUnitName == null)) {
782            return;
783        }
784        if (m_orgUnitResources == null) {
785            m_orgUnitResources = new HashMap<String, List<String>>();
786        }
787        List<String> resources = m_orgUnitResources.get(m_orgUnitName);
788        if (resources == null) {
789            resources = new ArrayList<String>();
790            m_orgUnitResources.put(m_orgUnitName, resources);
791        }
792        resources.add(resourceName);
793    }
794
795    /**
796     * Adds a new resource to be associated to the current project.<p>
797     *
798     * @param resourceName the resource name to add
799     */
800    public void addProjectResource(String resourceName) {
801
802        if ((m_throwable != null) || (m_projectName == null)) {
803            return;
804        }
805        if (m_projectResources == null) {
806            m_projectResources = new ArrayList<String>();
807        }
808        m_projectResources.add(resourceName);
809    }
810
811    /**
812     * Adds a property from the current xml data, in case the type is implicit given.<p>
813     *
814     * @see #addResourcePropertyRules(Digester, String)
815     */
816    public void addProperty() {
817
818        addProperty("individual");
819    }
820
821    /**
822     * Adds a property from the current xml data, in case the type is explicit given.<p>
823     *
824     * @param propertyType the type of the property to be added
825     *
826     * @see #addResourcePropertyRules(Digester, String)
827     */
828    public void addProperty(String propertyType) {
829
830        if (m_properties == null) {
831            // this list will be used and clean up in the importResource method
832            m_properties = new HashMap<String, CmsProperty>();
833        }
834        try {
835            if ((m_propertyName == null) || getIgnoredProperties().contains(m_propertyName)) {
836                // continue if the current property (name) should be ignored or is null
837                return;
838            }
839            CmsProperty property = m_properties.get(m_propertyName);
840            if (property == null) {
841                property = new CmsProperty();
842                property.setName(m_propertyName);
843                property.setAutoCreatePropertyDefinition(true);
844                m_properties.put(m_propertyName, property);
845            }
846
847            if (m_propertyValue == null) {
848                m_propertyValue = "";
849            }
850
851            if ((propertyType != null) && propertyType.equals(PROPERTY_ATTRIB_TYPE_SHARED)) {
852                // it is a shared/resource property value
853                property.setResourceValue(m_propertyValue);
854            } else {
855                // it is an individual/structure value
856                property.setStructureValue(m_propertyValue);
857            }
858        } finally {
859            m_propertyName = null;
860            m_propertyValue = null;
861        }
862    }
863
864    /**
865     * Adds a relation to be imported from the current xml data.<p>
866     *
867     * @see #addResourceRelationRules(Digester, String)
868     */
869    public void addRelation() {
870
871        try {
872            if (m_throwable != null) {
873                // relation data is corrupt, ignore relation
874                if (LOG.isWarnEnabled()) {
875                    LOG.warn(
876                        Messages.get().getBundle().key(
877                            Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_RELATION_1,
878                            m_destination),
879                        m_throwable);
880                }
881                getReport().println(m_throwable);
882                getReport().addError(m_throwable);
883                m_throwable = null;
884                return;
885            }
886            RelationData relData = new RelationData(m_relationPath, m_relationId, m_relationType);
887            m_relationsForResource.add(relData);
888            m_relationData.put(Integer.valueOf(m_fileCounter), relData);
889        } finally {
890            m_relationId = null;
891            m_relationPath = null;
892            m_relationType = null;
893        }
894    }
895
896    /**
897     * Adds the XML digester rules for a single import file.<p>
898     *
899     * @param digester the digester to add the rules to
900     */
901    public void addXmlDigesterRules(Digester digester) {
902
903        // first accounts
904        String xpath = CmsImportExportManager.N_EXPORT + "/" + N_ACCOUNTS + "/" + N_ORGUNITS + "/" + N_ORGUNIT + "/";
905        addAccountsOrgunitRules(digester, xpath);
906        addAccountsGroupRules(digester, xpath);
907        addAccountsUserRules(digester, xpath);
908        digester.addCallMethod(
909            CmsImportExportManager.N_EXPORT + "/" + N_ACCOUNTS + "/" + N_ORGUNITS + "/" + N_ORGUNIT,
910            "setMembership");
911
912        // then resources
913
914        // When encountering opening files tag, initialize some fields which keep track of multiple resources'  data
915        digester.addRule(CmsImportExportManager.N_EXPORT + "/" + N_FILES, new Rule() {
916
917            @SuppressWarnings("synthetic-access")
918            @Override
919            public void begin(String namespace, String name, Attributes attributes) throws Exception {
920
921                m_indexToStructureId = new HashMap<>();
922                m_relationData = ArrayListMultimap.create();
923
924            }
925        });
926
927        digester.addRule(CmsImportExportManager.N_EXPORT + "/" + N_FILES + "/" + N_FILE, new Rule() {
928
929            @Override
930            public void begin(String namespace, String name, Attributes attributes) throws Exception {
931
932                m_importACEs = true;
933                m_resourceBuilder = new CmsResourceBuilder();
934                m_resourceBuilder.setDateLastModified(DATE_LAST_MODIFICATION_UNSPECIFIED);
935                m_resourceBuilder.setDateReleased(CmsResource.DATE_RELEASED_DEFAULT);
936                m_resourceBuilder.setDateExpired(CmsResource.DATE_EXPIRED_DEFAULT);
937                m_resourceBuilder.setDateCreated(DATE_CREATED_UNSPECIFIED);
938                m_resourceBuilder.setUserCreated(CmsUUID.getNullUUID());
939                m_relationsForResource = new ArrayList<>();
940                m_hasStructureId = false;
941                m_hasDateLastModified = false;
942                m_unknownType = false;
943            }
944        });
945
946        xpath = CmsImportExportManager.N_EXPORT + "/" + N_FILES + "/" + N_FILE + "/";
947        addResourceAttributesRules(digester, xpath);
948        digester.addCallMethod(xpath, "importResourceAll");
949        addResourcePropertyRules(digester, xpath);
950        addResourceRelationRules(digester, xpath);
951        addResourceAceRules(digester, xpath);
952
953        digester.addCallMethod(CmsImportExportManager.N_EXPORT + "/" + N_FILES, "importRelations");
954        digester.addCallMethod(CmsImportExportManager.N_EXPORT + "/" + N_FILES, "rewriteParseables");
955
956        // and now the organizational unit resources
957        digester.addCallMethod(CmsImportExportManager.N_EXPORT + "/" + N_FILES, "associateOrgUnitResources");
958
959        // then projects
960        xpath = CmsImportExportManager.N_EXPORT + "/" + N_PROJECTS + "/" + N_PROJECT + "/";
961        addProjectRules(digester, xpath);
962    }
963
964    /**
965     * Adds the XML digester rules for pre-processing a single import file.<p>
966     *
967     * @param digester the digester to add the rules to
968     */
969    public void addXmlPreprocessingDigesterRules(Digester digester) {
970
971        digester.addCallMethod(CmsImportExportManager.N_EXPORT + "/" + N_FILES + "/" + N_FILE, "increaseTotalFiles");
972        digester.addCallMethod(
973            CmsImportExportManager.N_EXPORT
974                + "/"
975                + CmsImportExportManager.N_INFO
976                + "/"
977                + CmsImportExportManager.N_VERSION,
978            "setVersion",
979            0);
980    }
981
982    /**
983     * Associates the stored resources to the created organizational units.<p>
984     *
985     * This is a global process that occurs only once at the end of the import,
986     * after all resources have been imported, to make sure that the resources
987     * of the organizational units are available.<p>
988     *
989     * @see #addAccountsOrgunitRules(Digester, String)
990     * @see #addXmlDigesterRules(Digester)
991     */
992    public void associateOrgUnitResources() {
993
994        if ((m_orgUnitResources == null) || m_orgUnitResources.isEmpty()) {
995            // no organizational resources to associate
996            return;
997        }
998
999        String site = getRequestContext().getSiteRoot();
1000        try {
1001            getRequestContext().setSiteRoot("");
1002            List<String> orgUnits = new ArrayList<String>(m_orgUnitResources.keySet());
1003            Collections.sort(orgUnits);
1004            Iterator<String> it = orgUnits.iterator();
1005            while (it.hasNext()) {
1006                String orgUnitName = it.next();
1007                List<String> resources = m_orgUnitResources.get(orgUnitName);
1008
1009                if (orgUnitName.equals("")) {
1010                    continue;
1011                }
1012
1013                Iterator<String> itResources = resources.iterator();
1014                while (itResources.hasNext()) {
1015                    String resourceName = itResources.next();
1016                    try {
1017                        // Add the resource to the organizational unit
1018                        OpenCms.getOrgUnitManager().addResourceToOrgUnit(getCms(), orgUnitName, resourceName);
1019                    } catch (CmsException e) {
1020                        getReport().addWarning(e);
1021                        if (LOG.isWarnEnabled()) {
1022                            LOG.warn(e.getLocalizedMessage());
1023                        }
1024                        if (LOG.isDebugEnabled()) {
1025                            LOG.debug(e.getLocalizedMessage(), e);
1026                        }
1027                    }
1028                }
1029
1030                // remove the meanwhile used first resource of the parent organizational unit
1031                try {
1032                    String resName = (OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
1033                        getCms(),
1034                        CmsOrganizationalUnit.getParentFqn(orgUnitName)).get(0)).getRootPath();
1035                    if (!resources.contains(resName)) {
1036                        OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(getCms(), orgUnitName, resName);
1037                    }
1038                } catch (CmsException e) {
1039                    getReport().addWarning(e);
1040                    if (LOG.isWarnEnabled()) {
1041                        LOG.warn(e.getLocalizedMessage());
1042                    }
1043                    if (LOG.isDebugEnabled()) {
1044                        LOG.debug(e.getLocalizedMessage(), e);
1045                    }
1046                }
1047
1048            }
1049        } finally {
1050            getRequestContext().setSiteRoot(site);
1051        }
1052
1053        m_orgUnitResources = null;
1054    }
1055
1056    /**
1057     * Returns the ace Flags.<p>
1058     *
1059     * @return the ace Flags
1060     *
1061     * @see #N_FLAGS
1062     * @see #addResourceAceRules(Digester, String)
1063     */
1064    public int getAceFlags() {
1065
1066        return m_aceFlags;
1067    }
1068
1069    /**
1070     * Returns the ace Permissions Allowed.<p>
1071     *
1072     * @return the ace Permissions Allowed
1073     *
1074     * @see #N_ACCESSCONTROL_ALLOWEDPERMISSIONS
1075     * @see #addResourceAceRules(Digester, String)
1076     */
1077    public int getAcePermissionsAllowed() {
1078
1079        return m_acePermissionsAllowed;
1080    }
1081
1082    /**
1083     * Returns the acePermissionsDenied.<p>
1084     *
1085     * @return the acePermissionsDenied
1086     *
1087     * @see #N_ACCESSCONTROL_DENIEDPERMISSIONS
1088     * @see #addResourceAceRules(Digester, String)
1089     */
1090    public int getAcePermissionsDenied() {
1091
1092        return m_acePermissionsDenied;
1093    }
1094
1095    /**
1096     * Returns the acePrincipalId.<p>
1097     *
1098     * @return the acePrincipalId
1099     *
1100     * @see #N_ACCESSCONTROL_PRINCIPAL
1101     * @see #addResourceAceRules(Digester, String)
1102     */
1103    public CmsUUID getAcePrincipalId() {
1104
1105        return m_acePrincipalId;
1106    }
1107
1108    /**
1109     * Returns the cms object.<p>
1110     *
1111     * @return the cms object
1112     */
1113    public CmsObject getCms() {
1114
1115        return m_cms;
1116    }
1117
1118    /**
1119     * Returns the dateCreated.<p>
1120     *
1121     * @return the dateCreated
1122     *
1123     * @see #N_DATECREATED
1124     * @see #addResourceAttributesRules(Digester, String)
1125     */
1126    public long getDateCreated() {
1127
1128        return m_resourceBuilder.getDateCreated();
1129    }
1130
1131    /**
1132     * Returns the dateExpired.<p>
1133     *
1134     * @return the dateExpired
1135     *
1136     * @see #N_DATEEXPIRED
1137     * @see #addResourceAttributesRules(Digester, String)
1138     */
1139    public long getDateExpired() {
1140
1141        return m_resourceBuilder.getDateExpired();
1142    }
1143
1144    /**
1145     * Returns the dateLastModified.<p>
1146     *
1147     * @return the dateLastModified
1148     *
1149     * @see #N_DATELASTMODIFIED
1150     * @see #addResourceAttributesRules(Digester, String)
1151     */
1152    public long getDateLastModified() {
1153
1154        return m_resourceBuilder.getDateLastModified();
1155    }
1156
1157    /**
1158     * Returns the dateReleased.<p>
1159     *
1160     * @return the dateReleased
1161     *
1162     * @see #N_DATERELEASED
1163     * @see #addResourceAttributesRules(Digester, String)
1164     */
1165    public long getDateReleased() {
1166
1167        return m_resourceBuilder.getDateReleased();
1168    }
1169
1170    /**
1171     * Returns the destination.<p>
1172     *
1173     * @return the destination
1174     *
1175     * @see #N_DESTINATION
1176     * @see #addResourceAttributesRules(Digester, String)
1177     */
1178    public String getDestination() {
1179
1180        return m_destination;
1181    }
1182
1183    /**
1184     * Returns the flags.<p>
1185     *
1186     * @return the flags
1187     *
1188     * @see #N_FLAGS
1189     * @see #addResourceAttributesRules(Digester, String)
1190     */
1191    public int getFlags() {
1192
1193        return m_resourceBuilder.getFlags();
1194    }
1195
1196    /**
1197     * Returns the group Description.<p>
1198     *
1199     * @return the group Description
1200     */
1201    public String getGroupDescription() {
1202
1203        return m_groupDescription;
1204    }
1205
1206    /**
1207     * Returns the group Flags.<p>
1208     *
1209     * @return the group Flags
1210     */
1211    public int getGroupFlags() {
1212
1213        return m_groupFlags;
1214    }
1215
1216    /**
1217     * Returns the group Name.<p>
1218     *
1219     * @return the group Name
1220     */
1221    public String getGroupName() {
1222
1223        return m_groupName;
1224    }
1225
1226    /**
1227     * Returns the group Parent.<p>
1228     *
1229     * @return the group Parent
1230     */
1231    public String getGroupParent() {
1232
1233        return m_groupParent;
1234    }
1235
1236    /**
1237     * Returns the organizational unit description.<p>
1238     *
1239     * @return the organizational unit description
1240     */
1241    public String getOrgUnitDescription() {
1242
1243        return m_orgUnitDescription;
1244    }
1245
1246    /**
1247     * Returns the organizational unit flags.<p>
1248     *
1249     * @return the organizational unit flags
1250     */
1251    public int getOrgUnitFlags() {
1252
1253        return m_orgUnitFlags;
1254    }
1255
1256    /**
1257     * Returns the organizational unit name.<p>
1258     *
1259     * @return the organizational unit name
1260     */
1261    public String getOrgUnitName() {
1262
1263        return m_orgUnitName;
1264    }
1265
1266    /**
1267     * Returns the project Description.<p>
1268     *
1269     * @return the project Description
1270     */
1271    public String getProjectDescription() {
1272
1273        return m_projectDescription;
1274    }
1275
1276    /**
1277     * Returns the project Managers group name.<p>
1278     *
1279     * @return the project Managers group name
1280     */
1281    public String getProjectManagers() {
1282
1283        return m_projectManagers;
1284    }
1285
1286    /**
1287     * Returns the project Name.<p>
1288     *
1289     * @return the project Name
1290     */
1291    public String getProjectName() {
1292
1293        return m_projectName;
1294    }
1295
1296    /**
1297     * Returns the project Users group name.<p>
1298     *
1299     * @return the project Users group name
1300     */
1301    public String getProjectUsers() {
1302
1303        return m_projectUsers;
1304    }
1305
1306    /**
1307     * Returns the propertyName.<p>
1308     *
1309     * @return the propertyName
1310     *
1311     * @see #N_NAME
1312     * @see #addResourcePropertyRules(Digester, String)
1313     */
1314    public String getPropertyName() {
1315
1316        return m_propertyName;
1317    }
1318
1319    /**
1320     * Returns the propertyValue.<p>
1321     *
1322     * @return the propertyValue
1323     *
1324     * @see #N_VALUE
1325     * @see #addResourcePropertyRules(Digester, String)
1326     */
1327    public String getPropertyValue() {
1328
1329        return m_propertyValue;
1330    }
1331
1332    /**
1333     * Returns the relationId.<p>
1334     *
1335     * @return the relationId
1336     *
1337     * @see #N_ID
1338     * @see #addResourceRelationRules(Digester, String)
1339     */
1340    public CmsUUID getRelationId() {
1341
1342        return m_relationId;
1343    }
1344
1345    /**
1346     * Returns the relationPath.<p>
1347     *
1348     * @return the relationPath
1349     *
1350     * @see #N_PATH
1351     * @see #addResourceRelationRules(Digester, String)
1352     */
1353    public String getRelationPath() {
1354
1355        return m_relationPath;
1356    }
1357
1358    /**
1359     * Returns the relationType.<p>
1360     *
1361     * @return the relationType
1362     *
1363     * @see #N_TYPE
1364     * @see #addResourceRelationRules(Digester, String)
1365     */
1366    public CmsRelationType getRelationType() {
1367
1368        return m_relationType;
1369    }
1370
1371    /**
1372     * Returns the report.<p>
1373     *
1374     * @return the report
1375     */
1376    public I_CmsReport getReport() {
1377
1378        return m_report;
1379    }
1380
1381    /**
1382     * Gets the request context of the currently used CmsObject.<p>
1383     *
1384     * @return the current request context
1385     */
1386    public CmsRequestContext getRequestContext() {
1387
1388        return getCms().getRequestContext();
1389    }
1390
1391    /**
1392     * Returns the resourceId.<p>
1393     *
1394     * @return the resourceId
1395     *
1396     * @see #N_UUIDRESOURCE
1397     * @see #addResourceAttributesRules(Digester, String)
1398     */
1399    public CmsUUID getResourceId() {
1400
1401        return m_resourceBuilder.getResourceId();
1402    }
1403
1404    /**
1405     * Returns the source.<p>
1406     *
1407     * @return the source
1408     *
1409     * @see #N_SOURCE
1410     * @see #addResourceAttributesRules(Digester, String)
1411     */
1412    public String getSource() {
1413
1414        return m_source;
1415    }
1416
1417    /**
1418     * Returns the structureId.<p>
1419     *
1420     * @return the structureId
1421     *
1422     * @see #N_UUIDSTRUCTURE
1423     * @see #addResourceAttributesRules(Digester, String)
1424     */
1425    public CmsUUID getStructureId() {
1426
1427        return m_resourceBuilder.getStructureId();
1428    }
1429
1430    /**
1431     * Returns the throwable.<p>
1432     *
1433     * @return the throwable
1434     */
1435    public Throwable getThrowable() {
1436
1437        return m_throwable;
1438    }
1439
1440    /**
1441     * Returns the type.<p>
1442     *
1443     * @return the type
1444     *
1445     * @see #N_TYPE
1446     * @see #addResourceAttributesRules(Digester, String)
1447     */
1448    public I_CmsResourceType getType() {
1449
1450        return null;
1451    }
1452
1453    /**
1454     * Returns the userCreated.<p>
1455     *
1456     * @return the userCreated
1457     *
1458     * @see #N_USERCREATED
1459     * @see #addResourceAttributesRules(Digester, String)
1460     */
1461    public CmsUUID getUserCreated() {
1462
1463        return m_resourceBuilder.getUserCreated();
1464    }
1465
1466    /**
1467     * Returns the user Date Created.<p>
1468     *
1469     * @return the user Date Created
1470     */
1471    public long getUserDateCreated() {
1472
1473        return m_userDateCreated;
1474    }
1475
1476    /**
1477     * Returns the user Email address.<p>
1478     *
1479     * @return the user Email address
1480     */
1481    public String getUserEmail() {
1482
1483        return m_userEmail;
1484    }
1485
1486    /**
1487     * Returns the user First name.<p>
1488     *
1489     * @return the user First name
1490     */
1491    public String getUserFirstname() {
1492
1493        return m_userFirstname;
1494    }
1495
1496    /**
1497     * Returns the user Flags.<p>
1498     *
1499     * @return the user Flags
1500     */
1501    public int getUserFlags() {
1502
1503        return m_userFlags;
1504    }
1505
1506    /**
1507     * Returns the userLastModified.<p>
1508     *
1509     * @return the userLastModified
1510     *
1511     * @see #N_USERLASTMODIFIED
1512     * @see #addResourceAttributesRules(Digester, String)
1513     */
1514    public CmsUUID getUserLastModified() {
1515
1516        return m_resourceBuilder.getUserLastModified();
1517    }
1518
1519    /**
1520     * Returns the user Last name.<p>
1521     *
1522     * @return the user Last name
1523     */
1524    public String getUserLastname() {
1525
1526        return m_userLastname;
1527    }
1528
1529    /**
1530     * Returns the user Name.<p>
1531     *
1532     * @return the user Name
1533     */
1534    public String getUserName() {
1535
1536        return m_userName;
1537    }
1538
1539    /**
1540     * Returns the user Password.<p>
1541     *
1542     * @return the user Password
1543     */
1544    public String getUserPassword() {
1545
1546        return m_userPassword;
1547    }
1548
1549    /**
1550     * @see org.opencms.importexport.I_CmsImport#getVersion()
1551     */
1552    public int getVersion() {
1553
1554        return IMPORT_VERSION10;
1555    }
1556
1557    /**
1558     * Imports an ACE from the current xml data.<p>
1559     *
1560     * @see #addResourceAceRules(Digester, String)
1561     */
1562    public void importAccessControlEntries() {
1563
1564        // only set permissions if the resource did not exists or if the keep permissions flag is not set
1565        if ((m_resource == null) || !m_importACEs) {
1566            return;
1567        }
1568        if ((m_aces == null) || (m_aces.size() == 0)) {
1569            // no ACE in the list
1570            return;
1571        }
1572        // if the resource was imported add the access control entries if available
1573        try {
1574            getCms().importAccessControlEntries(m_resource, m_aces);
1575        } catch (@SuppressWarnings("unused") CmsException exc) {
1576            getReport().println(
1577                Messages.get().container(Messages.RPT_IMPORT_ACL_DATA_FAILED_0),
1578                I_CmsReport.FORMAT_WARNING);
1579        } finally {
1580            m_aces = null;
1581        }
1582    }
1583
1584    /**
1585     * @see org.opencms.importexport.I_CmsImport#importData(CmsObject, I_CmsReport, CmsImportParameters)
1586     */
1587    public void importData(CmsObject cms, I_CmsReport report, CmsImportParameters parameters) {
1588
1589        m_cms = cms;
1590        m_report = report;
1591        m_parameters = parameters;
1592
1593        // instantiate Digester and enable XML validation
1594        Digester digester = new Digester();
1595        digester.setUseContextClassLoader(true);
1596        digester.setValidating(m_parameters.isXmlValidation());
1597        digester.setEntityResolver(new CmsXmlEntityResolver(null));
1598        digester.setRuleNamespaceURI(null);
1599        digester.setErrorHandler(new CmsXmlErrorHandler(CmsImportExportManager.EXPORT_MANIFEST));
1600
1601        // add this object to the Digester
1602        digester.push(this);
1603
1604        addXmlDigesterRules(digester);
1605
1606        InputStream stream = null;
1607        m_helper = new CmsImportHelper(m_parameters);
1608        try {
1609            m_helper.openFile();
1610            m_helper.cacheDtdSystemId(DTD_LOCATION, DTD_FILENAME, CmsConfigurationManager.DEFAULT_DTD_PREFIX);
1611            findContentFiles();
1612            // start the parsing process
1613            stream = m_helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
1614            digester.parse(stream);
1615        } catch (Exception ioe) {
1616            if (LOG.isErrorEnabled()) {
1617                LOG.error(
1618                    Messages.get().getBundle().key(
1619                        Messages.ERR_IMPORTEXPORT_ERROR_READING_FILE_1,
1620                        CmsImportExportManager.EXPORT_MANIFEST),
1621                    ioe);
1622            }
1623            getReport().println(ioe);
1624        } finally {
1625            try {
1626                if (stream != null) {
1627                    stream.close();
1628                }
1629            } catch (@SuppressWarnings("unused") Exception e) {
1630                // noop
1631            }
1632            m_helper.closeFile();
1633        }
1634    }
1635
1636    /**
1637     * Import the current group from xml data.<p>
1638     */
1639    public void importGroup() {
1640
1641        if (m_orgUnit == null) {
1642            return;
1643        }
1644        if (m_groupDescription == null) {
1645            m_groupDescription = "";
1646        }
1647        if (m_groupParents == null) {
1648            m_groupParents = new HashMap<String, List<String>>();
1649        }
1650
1651        String groupName = m_orgUnit.getName() + m_groupName;
1652        try {
1653            if (m_throwable != null) {
1654                getReport().println(m_throwable);
1655
1656                CmsMessageContainer message = Messages.get().container(
1657                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_GROUP_1,
1658                    groupName);
1659                if (LOG.isDebugEnabled()) {
1660                    LOG.debug(message.key(), m_throwable);
1661                }
1662                m_throwable = null;
1663                return;
1664            }
1665
1666            getReport().print(Messages.get().container(Messages.RPT_IMPORT_GROUP_0), I_CmsReport.FORMAT_NOTE);
1667            getReport().print(
1668                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, groupName));
1669            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
1670
1671            try {
1672                getCms().readGroup(groupName);
1673                // the group already exists and will not be created
1674                getReport().println(Messages.get().container(Messages.RPT_NOT_CREATED_0), I_CmsReport.FORMAT_OK);
1675            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
1676                // ok, let's create it
1677                // first check the parent group
1678                CmsUUID parentGroupId = null;
1679                if (CmsStringUtil.isNotEmpty(m_groupParent)) {
1680                    try {
1681                        // parent group exists
1682                        parentGroupId = getCms().readGroup(m_groupParent).getId();
1683                    } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException exc) {
1684                        // parent group does not exist, remember to set the parent group later
1685                        List<String> childs = m_groupParents.get(m_groupParent);
1686                        if (childs == null) {
1687                            childs = new ArrayList<String>();
1688                            m_groupParents.put(m_groupParent, childs);
1689                        }
1690                        childs.add(groupName);
1691                    }
1692                }
1693
1694                getCms().createGroup(
1695                    groupName,
1696                    m_groupDescription,
1697                    m_groupFlags,
1698                    parentGroupId == null ? null : m_groupParent);
1699                getReport().println(
1700                    org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
1701                    I_CmsReport.FORMAT_OK);
1702
1703                // set parents that could not be set before
1704                List<String> childs = m_groupParents.remove(groupName);
1705                if (childs != null) {
1706                    Iterator<String> it = childs.iterator();
1707                    while (it.hasNext()) {
1708                        String childGroup = it.next();
1709                        getCms().setParentGroup(childGroup, groupName);
1710                    }
1711                }
1712            }
1713        } catch (Exception e) {
1714            getReport().println(e);
1715
1716            CmsMessageContainer message = Messages.get().container(
1717                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_GROUP_1,
1718                groupName);
1719            if (LOG.isDebugEnabled()) {
1720                LOG.debug(message.key(), e);
1721            }
1722        } finally {
1723            m_groupDescription = null;
1724            m_groupFlags = 0;
1725            m_groupName = null;
1726            m_groupParent = null;
1727            m_throwable = null;
1728        }
1729    }
1730
1731    /**
1732     * Imports the current organizational unit.<p>
1733     */
1734    public void importOrgUnit() {
1735
1736        try {
1737            if (m_throwable != null) {
1738                getReport().println(m_throwable);
1739                getReport().addError(m_throwable);
1740
1741                CmsMessageContainer message = Messages.get().container(
1742                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_ORGUNITS_0);
1743                if (LOG.isDebugEnabled()) {
1744                    LOG.debug(message.key(), m_throwable);
1745                }
1746                m_throwable = null;
1747                m_orgUnit = null;
1748
1749                return;
1750            }
1751
1752            getReport().print(Messages.get().container(Messages.RPT_IMPORT_ORGUNIT_0), I_CmsReport.FORMAT_NOTE);
1753            getReport().print(
1754                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, m_orgUnitName));
1755            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
1756
1757            try {
1758                m_orgUnit = OpenCms.getOrgUnitManager().readOrganizationalUnit(getCms(), m_orgUnitName);
1759                // the organizational unit already exists and will not be created
1760                getReport().println(Messages.get().container(Messages.RPT_NOT_CREATED_0), I_CmsReport.FORMAT_OK);
1761                m_orgUnitResources.remove(m_orgUnitName);
1762                return;
1763            } catch (@SuppressWarnings("unused") CmsDataAccessException e) {
1764                // ok, continue creating the ou
1765            }
1766
1767            // get the resources that already exist for the organizational unit
1768            // if there are resources that does not exist jet, there will be a second try after importing resources
1769            List<CmsResource> resources = new ArrayList<CmsResource>();
1770            String site = getRequestContext().getSiteRoot();
1771            try {
1772                getRequestContext().setSiteRoot("");
1773
1774                boolean remove = true;
1775                List<String> ouResources = CmsCollectionsGenericWrapper.list(m_orgUnitResources.get(m_orgUnitName));
1776                if (ouResources != null) {
1777                    Iterator<String> itResNames = ouResources.iterator();
1778                    while (itResNames.hasNext()) {
1779                        String resName = itResNames.next();
1780                        try {
1781                            resources.add(getCms().readResource(resName, CmsResourceFilter.ALL));
1782                            itResNames.remove();
1783                        } catch (@SuppressWarnings("unused") CmsVfsResourceNotFoundException e) {
1784                            // resource does not exist yet, skip it for now
1785                            remove = false;
1786                        }
1787                    }
1788                }
1789
1790                if (remove) {
1791                    m_orgUnitResources.remove(m_orgUnitName);
1792                }
1793            } finally {
1794                getRequestContext().setSiteRoot(site);
1795            }
1796
1797            // if no resource available
1798            if (resources.isEmpty()) {
1799                // meanwhile use the first one of the parent organizational unit
1800                resources.add(
1801                    OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
1802                        getCms(),
1803                        CmsOrganizationalUnit.getParentFqn(m_orgUnitName)).get(0));
1804            }
1805
1806            // create the organizational unit with a dummy resource, which will be corrected later
1807            m_orgUnit = OpenCms.getOrgUnitManager().createOrganizationalUnit(
1808                getCms(),
1809                m_orgUnitName,
1810                m_orgUnitDescription,
1811                m_orgUnitFlags,
1812                resources.get(0).getRootPath());
1813            for (int i = 1; i < resources.size(); i++) {
1814                OpenCms.getOrgUnitManager().addResourceToOrgUnit(
1815                    getCms(),
1816                    m_orgUnitName,
1817                    resources.get(i).getRootPath());
1818            }
1819
1820            getReport().println(
1821                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
1822                I_CmsReport.FORMAT_OK);
1823        } catch (CmsException e) {
1824            getReport().println(e);
1825            getReport().addError(e);
1826
1827            CmsMessageContainer message = Messages.get().container(
1828                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_ORGUNITS_0);
1829            if (LOG.isDebugEnabled()) {
1830                LOG.debug(message.key(), e);
1831            }
1832            m_throwable = null;
1833            m_orgUnit = null;
1834        } finally {
1835            m_orgUnitName = null;
1836            m_orgUnitDescription = null;
1837            m_orgUnitFlags = 0;
1838        }
1839
1840    }
1841
1842    /**
1843     * Imports the current project.<p>
1844     */
1845    public void importProject() {
1846
1847        try {
1848            if (m_throwable != null) {
1849                getReport().println(m_throwable);
1850                getReport().addError(m_throwable);
1851
1852                CmsMessageContainer message = Messages.get().container(
1853                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_PROJECTS_0);
1854                if (LOG.isDebugEnabled()) {
1855                    LOG.debug(message.key(), m_throwable);
1856                }
1857                m_throwable = null;
1858
1859                return;
1860            }
1861
1862            getReport().print(Messages.get().container(Messages.RPT_IMPORT_PROJECT_0), I_CmsReport.FORMAT_NOTE);
1863            getReport().print(
1864                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, m_projectName));
1865            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
1866
1867            try {
1868                getCms().readProject(m_projectName);
1869                // the project already exists and will not be created
1870                getReport().println(Messages.get().container(Messages.RPT_NOT_CREATED_0), I_CmsReport.FORMAT_OK);
1871                return;
1872            } catch (@SuppressWarnings("unused") CmsDataAccessException e) {
1873                // ok, continue creating the project
1874            }
1875
1876            // create the project
1877            CmsProject project = getCms().createProject(
1878                m_projectName,
1879                m_projectDescription,
1880                m_projectUsers,
1881                m_projectManagers,
1882                CmsProject.PROJECT_TYPE_NORMAL);
1883            // set the resources
1884            if (m_projectResources != null) {
1885                String site = getRequestContext().getSiteRoot();
1886                CmsProject currentProject = getRequestContext().getCurrentProject();
1887                try {
1888                    getRequestContext().setSiteRoot("");
1889                    getRequestContext().setCurrentProject(project);
1890
1891                    Iterator<String> itResNames = m_projectResources.iterator();
1892                    while (itResNames.hasNext()) {
1893                        String resName = itResNames.next();
1894                        try {
1895                            getCms().copyResourceToProject(resName);
1896                        } catch (@SuppressWarnings("unused") CmsVfsResourceNotFoundException e) {
1897                            // resource does not exist, skip
1898                        }
1899                    }
1900                } finally {
1901                    getRequestContext().setSiteRoot(site);
1902                    getRequestContext().setCurrentProject(currentProject);
1903                }
1904            }
1905            getReport().println(
1906                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
1907                I_CmsReport.FORMAT_OK);
1908        } catch (CmsException e) {
1909            getReport().println(e);
1910            getReport().addError(e);
1911
1912            CmsMessageContainer message = Messages.get().container(
1913                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_PROJECTS_0);
1914            if (LOG.isDebugEnabled()) {
1915                LOG.debug(message.key(), e);
1916            }
1917            m_throwable = null;
1918        } finally {
1919            m_projectName = null;
1920            m_projectDescription = null;
1921            m_projectManagers = null;
1922            m_projectUsers = null;
1923            m_projectResources = null;
1924        }
1925
1926    }
1927
1928    /**
1929     * Imports all relations from the current xml data.<p>
1930     *
1931     * This is a global process that occurs only once at the end of the import,
1932     * after all resources have been imported, to make sure that both resources
1933     * of the relations are available.<p>
1934     *
1935     * @see #addResourceRelationRules(Digester, String)
1936     * @see #addXmlDigesterRules(Digester)
1937     */
1938    public void importRelations() {
1939
1940        if ((m_relationData == null) || m_relationData.isEmpty()) {
1941            // no relations to add
1942            return;
1943        }
1944
1945        getReport().println(
1946            Messages.get().container(Messages.RPT_START_IMPORT_RELATIONS_0),
1947            I_CmsReport.FORMAT_HEADLINE);
1948
1949        int i = 0;
1950        CmsResourceFilter filter = CmsResourceFilter.ALL;
1951        for (Integer importIndex : m_relationData.keySet()) {
1952            CmsUUID structureId = m_indexToStructureId.get(importIndex);
1953            if (structureId == null) {
1954                continue;
1955            }
1956            Collection<RelationData> relationDataList = m_relationData.get(importIndex);
1957            try {
1958                CmsResource src = m_cms.readResource(structureId, filter);
1959                if (checkImmutable(src.getRootPath())) {
1960                    continue;
1961                }
1962                getReport().print(
1963                    org.opencms.report.Messages.get().container(
1964                        org.opencms.report.Messages.RPT_SUCCESSION_2,
1965                        String.valueOf(i + 1),
1966                        String.valueOf(m_relationData.keySet().size())),
1967                    I_CmsReport.FORMAT_NOTE);
1968
1969                getReport().print(
1970                    Messages.get().container(
1971                        Messages.RPT_IMPORTING_RELATIONS_FOR_2,
1972                        src.getRootPath(),
1973                        Integer.valueOf(m_relationData.keySet().size())),
1974                    I_CmsReport.FORMAT_NOTE);
1975                getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
1976                boolean withErrors = false;
1977                for (RelationData relationData : relationDataList) {
1978                    CmsResource target = null;
1979                    if (relationData.getTargetId() != null) {
1980                        try {
1981                            target = m_cms.readResource(relationData.getTargetId(), filter);
1982                        } catch (CmsVfsResourceNotFoundException e) {
1983                            // ignore
1984                        }
1985                    }
1986                    if (target == null) {
1987                        try {
1988                            target = m_cms.readResource(relationData.getTarget(), filter);
1989                        } catch (CmsVfsResourceNotFoundException e) {
1990                            // ignore
1991                        }
1992                    }
1993
1994                    if (target != null) {
1995                        try {
1996                            getCms().importRelation(
1997                                m_cms.getSitePath(src),
1998                                m_cms.getSitePath(target),
1999                                relationData.getType().toString());
2000                        } catch (CmsException e) {
2001                            getReport().addWarning(e);
2002                            withErrors = true;
2003                            if (LOG.isWarnEnabled()) {
2004                                LOG.warn(e.getLocalizedMessage());
2005                            }
2006                            if (LOG.isDebugEnabled()) {
2007                                LOG.debug(e.getLocalizedMessage(), e);
2008                            }
2009                        }
2010                    }
2011                }
2012                if (!withErrors) {
2013                    getReport().println(
2014                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
2015                        I_CmsReport.FORMAT_OK);
2016                } else {
2017                    getReport().println(
2018                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0),
2019                        I_CmsReport.FORMAT_ERROR);
2020                }
2021                i += 1;
2022
2023            } catch (CmsException e) {
2024                getReport().addError(e);
2025                LOG.error(e.getLocalizedMessage(), e);
2026                continue;
2027            }
2028        }
2029    }
2030
2031    /**
2032     * Imports a resource from the current xml data.<p>
2033     *
2034     * @see #addResourceAttributesRules(Digester, String)
2035     * @see #addResourcePropertyRules(Digester, String)
2036     */
2037    public void importResource() {
2038
2039        m_resourceIdWasNull = false;
2040
2041        try {
2042            if (m_throwable != null) {
2043                getReport().println(m_throwable);
2044                getReport().addError(m_throwable);
2045
2046                CmsMessageContainer message = Messages.get().container(
2047                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_RESOURCES_0);
2048                if (LOG.isDebugEnabled()) {
2049                    LOG.debug(message.key(), m_throwable);
2050                }
2051                m_throwable = null;
2052                m_importACEs = false;
2053                m_resource = null;
2054
2055                return;
2056            }
2057
2058            // apply name translation and import path
2059            String translatedName = getRequestContext().addSiteRoot(
2060                CmsStringUtil.joinPaths(m_parameters.getDestinationPath(), m_destination));
2061
2062            boolean skipResource = checkImmutable(translatedName);
2063            translatedName = getRequestContext().removeSiteRoot(translatedName);
2064            // if the resource is not immutable and not on the exclude list, import it
2065            if (!skipResource) {
2066                if (!m_hasStructureId && isFolderType(m_typeName) && getCms().existsResource(translatedName, CmsResourceFilter.ALL)) {
2067                    skipResource = true;
2068                }
2069            }
2070            if (!skipResource) {
2071                // print out the information to the report
2072                getReport().print(Messages.get().container(Messages.RPT_IMPORTING_0), I_CmsReport.FORMAT_NOTE);
2073                getReport().print(
2074                    org.opencms.report.Messages.get().container(
2075                        org.opencms.report.Messages.RPT_ARGUMENT_1,
2076                        translatedName));
2077                getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
2078
2079                boolean exists = getCms().existsResource(translatedName, CmsResourceFilter.ALL);
2080
2081                byte[] content = null;
2082                // get the file content
2083
2084                if (m_source != null) {
2085                    content = m_helper.getFileBytes(m_source);
2086                }
2087                int size = 0;
2088                if (content != null) {
2089                    size = content.length;
2090                }
2091                setDefaultsForEmptyResourceFields();
2092                // create a new CmsResource
2093                CmsResource resource = createResourceObjectFromFields(translatedName, size);
2094                if (!OpenCms.getResourceManager().hasResourceType(m_typeName)) {
2095                    m_properties.put(
2096                        CmsPropertyDefinition.PROPERTY_EXPORT_TYPE,
2097                        new CmsProperty(CmsPropertyDefinition.PROPERTY_EXPORT_TYPE, null, m_typeName, true));
2098                }
2099                if (m_resourceBuilder.getType().isFolder()
2100                    || m_resourceIdWasNull
2101                    || hasContentInVfsOrImport(resource)) {
2102                    // import this resource in the VFS
2103                    m_resource = getCms().importResource(
2104                        translatedName,
2105                        getReport(),
2106                        resource,
2107                        content,
2108                        new ArrayList<CmsProperty>(m_properties.values()));
2109                }
2110
2111                if (m_resource != null) {
2112                    m_indexToStructureId.put(Integer.valueOf(m_fileCounter), m_resource.getStructureId());
2113                }
2114
2115                // only set permissions if the resource did not exists or if the keep permissions flag is not set
2116                m_importACEs = (m_resource != null) && (!exists || !m_parameters.isKeepPermissions());
2117
2118                if (m_resource != null) {
2119                    getReport().println(
2120                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
2121                        I_CmsReport.FORMAT_OK);
2122
2123                    if (OpenCms.getResourceManager().getResourceType(
2124                        m_resource.getTypeId()) instanceof I_CmsLinkParseable) {
2125                        // store for later use
2126                        m_parseables.add(m_resource);
2127                    }
2128                    if (LOG.isInfoEnabled()) {
2129                        LOG.info(
2130                            Messages.get().getBundle().key(
2131                                Messages.LOG_IMPORTING_4,
2132                                new Object[] {
2133                                    String.valueOf(m_fileCounter),
2134                                    String.valueOf(m_totalFiles),
2135                                    translatedName,
2136                                    m_destination}));
2137                    }
2138                } else {
2139                    // resource import failed, since no CmsResource was created
2140                    getReport().print(Messages.get().container(Messages.RPT_SKIPPING_0), I_CmsReport.FORMAT_NOTE);
2141                    getReport().println(
2142                        org.opencms.report.Messages.get().container(
2143                            org.opencms.report.Messages.RPT_ARGUMENT_1,
2144                            translatedName));
2145
2146                    if (LOG.isInfoEnabled()) {
2147                        LOG.info(
2148                            Messages.get().getBundle().key(
2149                                Messages.LOG_SKIPPING_3,
2150                                String.valueOf(m_fileCounter),
2151                                String.valueOf(m_totalFiles),
2152                                translatedName));
2153                    }
2154                }
2155            } else {
2156                m_resource = null;
2157                // skip the file import, just print out the information to the report
2158                getReport().print(Messages.get().container(Messages.RPT_SKIPPING_0), I_CmsReport.FORMAT_NOTE);
2159                getReport().println(
2160                    org.opencms.report.Messages.get().container(
2161                        org.opencms.report.Messages.RPT_ARGUMENT_1,
2162                        translatedName));
2163
2164                if (LOG.isInfoEnabled()) {
2165                    LOG.info(
2166                        Messages.get().getBundle().key(
2167                            Messages.LOG_SKIPPING_3,
2168                            String.valueOf(m_fileCounter),
2169                            String.valueOf(m_totalFiles),
2170                            translatedName));
2171                }
2172                // do not import ACEs
2173                m_importACEs = false;
2174            }
2175        } catch (Exception e) {
2176            m_resource = null;
2177            m_importACEs = false;
2178
2179            getReport().println(e);
2180            getReport().addError(e);
2181
2182            CmsMessageContainer message = Messages.get().container(
2183                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_RESOURCES_0);
2184            if (LOG.isDebugEnabled()) {
2185                LOG.debug(message.key(), e);
2186            }
2187
2188            return;
2189        }
2190    }
2191
2192    /**
2193     * Imports the resource and access control entries.<p>
2194     */
2195    public void importResourceAll() {
2196
2197        try {
2198            importResource();
2199            importAccessControlEntries();
2200            increaseCounter();
2201        } finally {
2202            m_destination = null;
2203            m_source = null;
2204            m_throwable = null;
2205            m_properties = null;
2206            m_aces = null;
2207        }
2208    }
2209
2210    /**
2211     * @see org.opencms.importexport.I_CmsImport#importResources(org.opencms.file.CmsObject, java.lang.String, org.opencms.report.I_CmsReport, java.io.File, java.util.zip.ZipFile, org.dom4j.Document)
2212     *
2213     * @deprecated use {@link #importData(CmsObject, I_CmsReport, CmsImportParameters)} instead
2214     */
2215    @Deprecated
2216    public void importResources(
2217        CmsObject cms,
2218        String importPath,
2219        I_CmsReport report,
2220        File importResource,
2221        ZipFile importZip,
2222        Document docXml) {
2223
2224        CmsImportParameters params = new CmsImportParameters(importResource.getAbsolutePath(), importPath, true);
2225
2226        importData(cms, report, params);
2227    }
2228
2229    /**
2230     * Imports a new user from the current xml data.<p>
2231     */
2232    public void importUser() {
2233
2234        // create a new user id
2235        String userName = m_orgUnit.getName() + m_userName;
2236        try {
2237            if (m_throwable != null) {
2238                m_user = null;
2239                getReport().println(m_throwable);
2240
2241                CmsMessageContainer message = Messages.get().container(
2242                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USER_1,
2243                    userName);
2244                if (LOG.isDebugEnabled()) {
2245                    LOG.debug(message.key(), m_throwable);
2246                }
2247                m_throwable = null;
2248                return;
2249            }
2250
2251            getReport().print(Messages.get().container(Messages.RPT_IMPORT_USER_0), I_CmsReport.FORMAT_NOTE);
2252            getReport().print(
2253                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, userName));
2254            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
2255
2256            try {
2257                getCms().readUser(userName);
2258                // user exists already
2259                getReport().println(Messages.get().container(Messages.RPT_NOT_CREATED_0), I_CmsReport.FORMAT_OK);
2260                m_user = null;
2261                return;
2262            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2263                // user does not exist
2264            }
2265
2266            CmsParameterConfiguration config = OpenCms.getPasswordHandler().getConfiguration();
2267            if ((config != null) && config.containsKey(I_CmsPasswordHandler.CONVERT_DIGEST_ENCODING)) {
2268                if (config.getBoolean(I_CmsPasswordHandler.CONVERT_DIGEST_ENCODING, false)) {
2269                    m_userPassword = convertDigestEncoding(m_userPassword);
2270                }
2271            }
2272
2273            m_user = getCms().importUser(
2274                new CmsUUID().toString(),
2275                userName,
2276                m_userPassword,
2277                m_userFirstname,
2278                m_userLastname,
2279                m_userEmail,
2280                m_userFlags,
2281                m_userDateCreated,
2282                m_userInfos);
2283
2284            getReport().println(
2285                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
2286                I_CmsReport.FORMAT_OK);
2287        } catch (Throwable e) {
2288            m_user = null;
2289            getReport().println(e);
2290
2291            CmsMessageContainer message = Messages.get().container(
2292                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USER_1,
2293                userName);
2294            if (LOG.isDebugEnabled()) {
2295                LOG.debug(message.key(), e);
2296            }
2297        } finally {
2298            m_userName = null;
2299            m_userPassword = null;
2300            m_userFirstname = null;
2301            m_userLastname = null;
2302            m_userEmail = null;
2303            m_userFlags = 0;
2304            m_userDateCreated = 0;
2305            m_userInfos = null;
2306        }
2307    }
2308
2309    /**
2310     * Sets the current user as member of the given group.<p>
2311     *
2312     * It can happen that the organizational unit has not been imported jet,
2313     * in this case, the data is kept for later.<p>
2314     *
2315     * @param groupName the name of the group to set
2316     *
2317     * @see #setMembership()
2318     */
2319    public void importUserGroup(String groupName) {
2320
2321        if ((m_throwable != null) || (m_user == null)) {
2322            return;
2323        }
2324        groupName = OpenCms.getImportExportManager().translateGroup(groupName);
2325        try {
2326            String ouName = CmsOrganizationalUnit.getParentFqn(groupName);
2327            try {
2328                // check if the organizational unit exists
2329                OpenCms.getOrgUnitManager().readOrganizationalUnit(getCms(), ouName);
2330                // set the user group
2331                getCms().addUserToGroup(m_user.getName(), groupName);
2332                return;
2333            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2334                // organizational unit does not exist
2335            }
2336            // remember the user and group for later
2337            Map<String, Map<String, String>> membership = m_membership.get(ouName);
2338            if (membership == null) {
2339                membership = new HashMap<String, Map<String, String>>();
2340                m_membership.put(ouName, membership);
2341            }
2342            Map<String, String> groups = membership.get(I_CmsPrincipal.PRINCIPAL_GROUP);
2343            if (groups == null) {
2344                groups = new HashMap<String, String>();
2345                membership.put(I_CmsPrincipal.PRINCIPAL_GROUP, groups);
2346            }
2347            groups.put(m_user.getName(), groupName);
2348        } catch (Throwable e) {
2349            getReport().println(
2350                Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_GROUP_2, m_user.getName(), groupName),
2351                I_CmsReport.FORMAT_WARNING);
2352            if (LOG.isDebugEnabled()) {
2353                LOG.debug(e.getLocalizedMessage(), e);
2354            }
2355        }
2356    }
2357
2358    /**
2359     * Creates a new additional information entry for the current user.<p>
2360     *
2361     * @param infoName the name of the additional information entry
2362     * @param infoType the type of the additional information entry
2363     * @param infoValue the value of the additional information entry
2364     */
2365    public void importUserInfo(String infoName, String infoType, String infoValue) {
2366
2367        if (m_userInfos == null) {
2368            m_userInfos = new HashMap<String, Object>();
2369        }
2370        try {
2371            m_userInfos.put(infoName, CmsDataTypeUtil.dataImport(infoValue, infoType));
2372        } catch (Throwable e) {
2373            if (LOG.isErrorEnabled()) {
2374                LOG.error(e.getLocalizedMessage(), e);
2375            }
2376        }
2377    }
2378
2379    /**
2380     * Sets the current user as member of the given role.<p>
2381     *
2382     * It can happen that the organizational unit has not been imported jet,
2383     * in this case, the data is kept for later.<p>
2384     *
2385     * @param roleName the name of the role to set
2386     *
2387     * @see #setMembership()
2388     */
2389    public void importUserRole(String roleName) {
2390
2391        if ((m_throwable != null) || (m_user == null)) {
2392            return;
2393        }
2394        try {
2395            CmsRole role = CmsRole.valueOfRoleName(roleName);
2396            try {
2397                // check if the organizational unit exists
2398                OpenCms.getOrgUnitManager().readOrganizationalUnit(getCms(), role.getOuFqn());
2399                // set the user role
2400                OpenCms.getRoleManager().addUserToRole(getCms(), role, m_user.getName());
2401                return;
2402            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2403                // organizational unit does not exist
2404            }
2405            // remember the user and role for later
2406            Map<String, Map<String, String>> membership = m_membership.get(role.getOuFqn());
2407            if (membership == null) {
2408                membership = new HashMap<String, Map<String, String>>();
2409                m_membership.put(role.getOuFqn(), membership);
2410            }
2411            Map<String, String> roles = membership.get(I_CmsPrincipal.PRINCIPAL_USER);
2412            if (roles == null) {
2413                roles = new HashMap<String, String>();
2414                membership.put(I_CmsPrincipal.PRINCIPAL_USER, roles);
2415            }
2416            roles.put(m_user.getName(), role.getFqn());
2417        } catch (Throwable e) {
2418            getReport().println(
2419                Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_ROLE_2, m_user.getName(), roleName),
2420                I_CmsReport.FORMAT_WARNING);
2421            if (LOG.isDebugEnabled()) {
2422                LOG.debug(e.getLocalizedMessage(), e);
2423            }
2424        }
2425    }
2426
2427    /**
2428     * Increases the file counter.<p>
2429     */
2430    public void increaseCounter() {
2431
2432        m_fileCounter++;
2433    }
2434
2435    /**
2436     * Increases the total number of files.<p>
2437     */
2438    public void increaseTotalFiles() {
2439
2440        m_totalFiles++;
2441    }
2442
2443    /**
2444     * @see org.opencms.importexport.I_CmsImport#matches(org.opencms.importexport.CmsImportParameters)
2445     */
2446    @SuppressWarnings("resource") //stream is closed always in finally block - don't know why the compiler complains
2447    public boolean matches(CmsImportParameters parameters) throws CmsImportExportException {
2448
2449        m_fileCounter = 1;
2450        m_totalFiles = 0;
2451        m_parseables = new ArrayList<CmsResource>();
2452
2453        m_parameters = parameters;
2454
2455        // instantiate Digester and enable XML validation
2456        Digester digester = new Digester();
2457        digester.setUseContextClassLoader(true);
2458        digester.setValidating(m_parameters.isXmlValidation());
2459        digester.setEntityResolver(new CmsXmlEntityResolver(null));
2460        digester.setRuleNamespaceURI(null);
2461        digester.setErrorHandler(new CmsXmlErrorHandler(CmsImportExportManager.EXPORT_MANIFEST));
2462
2463        // add this object to the Digester
2464        digester.push(this);
2465
2466        addXmlPreprocessingDigesterRules(digester);
2467
2468        InputStream stream = null;
2469        m_helper = new CmsImportHelper(m_parameters);
2470        m_helper.cacheDtdSystemId(DTD_LOCATION, DTD_FILENAME, CmsConfigurationManager.DEFAULT_DTD_PREFIX);
2471        try {
2472            m_helper.openFile();
2473            // start the parsing process
2474            // this will set the version attribute
2475            stream = m_helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
2476            digester.parse(stream);
2477        } catch (Exception ioe) {
2478            CmsMessageContainer msg = Messages.get().container(
2479                Messages.ERR_IMPORTEXPORT_ERROR_READING_FILE_1,
2480                CmsImportExportManager.EXPORT_MANIFEST);
2481            if (LOG.isErrorEnabled()) {
2482                LOG.error(msg.key(), ioe);
2483            }
2484            throw new CmsImportExportException(msg, ioe);
2485        } finally {
2486            try {
2487                if (stream != null) {
2488                    stream.close();
2489                }
2490            } catch (@SuppressWarnings("unused") Exception e) {
2491                // noop
2492            }
2493            m_helper.closeFile();
2494        }
2495        return (m_version == getVersion());
2496    }
2497
2498    /**
2499     * Rewrites all parseable files, to assure link check.<p>
2500     *
2501     * This is a global process, that is executed only once at the
2502     * end of the import to be sure that all link targets are
2503     * available.<p>
2504     *
2505     * @see #addXmlDigesterRules(Digester)
2506     */
2507    public void rewriteParseables() {
2508
2509        if (m_parseables.isEmpty()) {
2510            return;
2511        }
2512
2513        I_CmsReport report = getReport();
2514        CmsObject cms = getCms();
2515        cms.getRequestContext().setAttribute(CmsLogEntry.ATTR_LOG_ENTRY, Boolean.FALSE);
2516        report.println(Messages.get().container(Messages.RPT_START_PARSE_LINKS_0), I_CmsReport.FORMAT_HEADLINE);
2517        parseLinks(cms, m_parseables, report);
2518        report.println(Messages.get().container(Messages.RPT_END_PARSE_LINKS_0), I_CmsReport.FORMAT_HEADLINE);
2519        m_parseables = null;
2520    }
2521
2522    /**
2523     * Sets the aceFlags.<p>
2524     *
2525     * @param aceFlags the aceFlags to set
2526     *
2527     * @see #N_FLAGS
2528     * @see #addResourceAceRules(Digester, String)
2529     */
2530    public void setAceFlags(String aceFlags) {
2531
2532        try {
2533            m_aceFlags = Integer.parseInt(aceFlags);
2534        } catch (Throwable e) {
2535            m_throwable = e;
2536        }
2537    }
2538
2539    /**
2540     * Sets the acePermissionsAllowed.<p>
2541     *
2542     * @param acePermissionsAllowed the acePermissionsAllowed to set
2543     *
2544     * @see #N_ACCESSCONTROL_ALLOWEDPERMISSIONS
2545     * @see #addResourceAceRules(Digester, String)
2546     */
2547    public void setAcePermissionsAllowed(String acePermissionsAllowed) {
2548
2549        try {
2550            m_acePermissionsAllowed = Integer.parseInt(acePermissionsAllowed);
2551        } catch (Throwable e) {
2552            m_throwable = e;
2553        }
2554    }
2555
2556    /**
2557     * Sets the acePermissionsDenied.<p>
2558     *
2559     * @param acePermissionsDenied the acePermissionsDenied to set
2560     *
2561     * @see #N_ACCESSCONTROL_DENIEDPERMISSIONS
2562     * @see #addResourceAceRules(Digester, String)
2563     */
2564    public void setAcePermissionsDenied(String acePermissionsDenied) {
2565
2566        try {
2567            m_acePermissionsDenied = Integer.parseInt(acePermissionsDenied);
2568        } catch (Throwable e) {
2569            m_throwable = e;
2570        }
2571    }
2572
2573    /**
2574     * Sets the acePrincipalId.<p>
2575     *
2576     * @param acePrincipalId the acePrincipalId to set
2577     *
2578     * @see #N_ACCESSCONTROL_PRINCIPAL
2579     * @see #addResourceAceRules(Digester, String)
2580     */
2581    public void setAcePrincipalId(String acePrincipalId) {
2582
2583        try {
2584            CmsUUID principalId = null;
2585            String principal = acePrincipalId.substring(acePrincipalId.indexOf('.') + 1, acePrincipalId.length());
2586            if (acePrincipalId.startsWith(I_CmsPrincipal.PRINCIPAL_GROUP)) {
2587                principal = OpenCms.getImportExportManager().translateGroup(principal);
2588                principalId = getCms().readGroup(principal).getId();
2589            } else if (acePrincipalId.startsWith(I_CmsPrincipal.PRINCIPAL_USER)) {
2590                principal = OpenCms.getImportExportManager().translateUser(principal);
2591                principalId = getCms().readUser(principal).getId();
2592            } else if (acePrincipalId.startsWith(CmsRole.PRINCIPAL_ROLE)) {
2593                principalId = CmsRole.valueOfRoleName(principal).getId();
2594            } else if (acePrincipalId.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME)) {
2595                principalId = CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID;
2596            } else if (acePrincipalId.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME)) {
2597                principalId = CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID;
2598            } else {
2599                if (LOG.isWarnEnabled()) {
2600                    LOG.warn(
2601                        Messages.get().getBundle().key(
2602                            Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_ACE_1,
2603                            acePrincipalId));
2604                }
2605                throw new CmsIllegalStateException(
2606                    Messages.get().container(Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_ACE_1, acePrincipalId));
2607            }
2608            m_acePrincipalId = principalId;
2609        } catch (Throwable e) {
2610            setThrowable(e);
2611        }
2612    }
2613
2614    /**
2615     * Sets the dateCreated.<p>
2616     *
2617     * @param dateCreated the dateCreated to set
2618     *
2619     * @see #N_DATECREATED
2620     * @see #addResourceAttributesRules(Digester, String)
2621     */
2622    public void setDateCreated(String dateCreated) {
2623
2624        try {
2625            if (dateCreated != null) {
2626                m_resourceBuilder.setDateCreated(convertTimestamp(dateCreated));
2627            } else {
2628                m_resourceBuilder.setDateCreated(System.currentTimeMillis());
2629            }
2630        } catch (Throwable e) {
2631            setThrowable(e);
2632        }
2633    }
2634
2635    /**
2636     * Sets the dateExpired.<p>
2637     *
2638     * @param dateExpired the dateExpired to set
2639     *
2640     * @see #N_DATEEXPIRED
2641     * @see #addResourceAttributesRules(Digester, String)
2642     */
2643    public void setDateExpired(String dateExpired) {
2644
2645        try {
2646            if (dateExpired != null) {
2647                m_resourceBuilder.setDateExpired(convertTimestamp(dateExpired));
2648            } else {
2649                m_resourceBuilder.setDateExpired(CmsResource.DATE_EXPIRED_DEFAULT);
2650            }
2651        } catch (Throwable e) {
2652            setThrowable(e);
2653        }
2654    }
2655
2656    /**
2657     * Sets the dateLastModified.<p>
2658     *
2659     * @param dateLastModified the dateLastModified to set
2660     *
2661     * @see #N_DATELASTMODIFIED
2662     * @see #addResourceAttributesRules(Digester, String)
2663     */
2664    public void setDateLastModified(String dateLastModified) {
2665
2666        m_hasDateLastModified = true;
2667        try {
2668            if (dateLastModified != null) {
2669                TimestampMode timeMode = TimestampMode.getEnum(CmsMacroResolver.stripMacro(dateLastModified));
2670                switch (timeMode) {
2671                    case FILETIME:
2672                        m_resourceBuilder.setDateLastModified(-1); //Can't get the information right now, must set it afterward.
2673                        break;
2674                    case IMPORTTIME:
2675                        m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
2676                        break;
2677                    case VFSTIME:
2678                    default:
2679                        m_resourceBuilder.setDateLastModified(convertTimestamp(dateLastModified));
2680                        break;
2681                }
2682            } else {
2683                m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
2684            }
2685        } catch (Throwable e) {
2686            setThrowable(e);
2687        }
2688    }
2689
2690    /**
2691     * Sets the dateReleased.<p>
2692     *
2693     * @param dateReleased the dateReleased to set
2694     *
2695     * @see #N_DATERELEASED
2696     * @see #addResourceAttributesRules(Digester, String)
2697     */
2698    public void setDateReleased(String dateReleased) {
2699
2700        try {
2701            if (dateReleased != null) {
2702                m_resourceBuilder.setDateReleased(convertTimestamp(dateReleased));
2703            } else {
2704                m_resourceBuilder.setDateReleased(CmsResource.DATE_RELEASED_DEFAULT);
2705            }
2706        } catch (Throwable e) {
2707            setThrowable(e);
2708        }
2709    }
2710
2711    /**
2712     * Sets the destination.<p>
2713     *
2714     * @param destination the destination to set
2715     *
2716     * @see #N_DESTINATION
2717     * @see #addResourceAttributesRules(Digester, String)
2718     */
2719    public void setDestination(String destination) {
2720
2721        m_destination = destination;
2722    }
2723
2724    /**
2725     * Sets the flags.<p>
2726     *
2727     * @param flags the flags to set
2728     *
2729     * @see #N_FLAGS
2730     * @see #addResourceAttributesRules(Digester, String)
2731     */
2732    public void setFlags(String flags) {
2733
2734        try {
2735            m_resourceBuilder.setFlags(Integer.parseInt(flags));
2736        } catch (Throwable e) {
2737            setThrowable(e);
2738        }
2739    }
2740
2741    /**
2742     * Sets the group Description.<p>
2743     *
2744     * @param groupDescription the description to set
2745     */
2746    public void setGroupDescription(String groupDescription) {
2747
2748        m_groupDescription = groupDescription;
2749    }
2750
2751    /**
2752     * Sets the group Flags.<p>
2753     *
2754     * @param groupFlags the flags to set
2755     */
2756    public void setGroupFlags(String groupFlags) {
2757
2758        try {
2759            m_groupFlags = Integer.parseInt(groupFlags);
2760        } catch (Throwable e) {
2761            setThrowable(e);
2762        }
2763    }
2764
2765    /**
2766     * Sets the group Name.<p>
2767     *
2768     * @param groupName the name to set
2769     */
2770    public void setGroupName(String groupName) {
2771
2772        m_groupName = OpenCms.getImportExportManager().translateGroup(groupName);
2773    }
2774
2775    /**
2776     * Sets the group Parent.<p>
2777     *
2778     * @param groupParent the group Parent to set
2779     */
2780    public void setGroupParent(String groupParent) {
2781
2782        m_groupParent = OpenCms.getImportExportManager().translateGroup(groupParent);
2783    }
2784
2785    /**
2786     * Sets the membership information that could not been set immediately,
2787     * because of import order issues.<p>
2788     */
2789    public void setMembership() {
2790
2791        if ((m_orgUnit == null) || (m_membership == null)) {
2792            return;
2793        }
2794
2795        // get the membership data to set
2796        Map<String, Map<String, String>> membership = m_membership.get(m_orgUnit.getName());
2797        if (membership == null) {
2798            return;
2799        }
2800
2801        // set group membership
2802        Map<String, String> groups = membership.get(I_CmsPrincipal.PRINCIPAL_GROUP);
2803        if (groups != null) {
2804            Iterator<Entry<String, String>> it = groups.entrySet().iterator();
2805            while (it.hasNext()) {
2806                Entry<String, String> entry = it.next();
2807                String userName = entry.getKey();
2808                String groupName = entry.getValue();
2809
2810                // set the users group
2811                try {
2812                    getCms().addUserToGroup(userName, groupName);
2813                } catch (Throwable e) {
2814                    getReport().println(
2815                        Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_GROUP_2, userName, groupName),
2816                        I_CmsReport.FORMAT_WARNING);
2817                    if (LOG.isDebugEnabled()) {
2818                        LOG.debug(e.getLocalizedMessage(), e);
2819                    }
2820                }
2821            }
2822        }
2823
2824        // set role membership
2825        Map<String, String> roles = membership.get(I_CmsPrincipal.PRINCIPAL_USER);
2826        if (roles != null) {
2827            Iterator<Entry<String, String>> it = roles.entrySet().iterator();
2828            while (it.hasNext()) {
2829                Entry<String, String> entry = it.next();
2830                String userName = entry.getKey();
2831                String roleName = entry.getValue();
2832
2833                // set the users roles
2834                CmsRole role = CmsRole.valueOfRoleName(roleName);
2835                try {
2836                    // set the user role
2837                    OpenCms.getRoleManager().addUserToRole(getCms(), role, userName);
2838                    return;
2839                } catch (Throwable e) {
2840                    getReport().println(
2841                        Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_ROLE_2, userName, roleName),
2842                        I_CmsReport.FORMAT_WARNING);
2843                    if (LOG.isDebugEnabled()) {
2844                        LOG.debug(e.getLocalizedMessage(), e);
2845                    }
2846                }
2847            }
2848        }
2849    }
2850
2851    /**
2852     * Sets the organizational unit description.<p>
2853     *
2854     * @param orgUnitDescription the description to set
2855     */
2856    public void setOrgUnitDescription(String orgUnitDescription) {
2857
2858        m_orgUnitDescription = orgUnitDescription;
2859    }
2860
2861    /**
2862     * Sets the organizational unit flags.<p>
2863     *
2864     * @param orgUnitFlags the flags to set
2865     */
2866    public void setOrgUnitFlags(String orgUnitFlags) {
2867
2868        try {
2869            m_orgUnitFlags = Integer.parseInt(orgUnitFlags);
2870        } catch (Throwable e) {
2871            setThrowable(e);
2872        }
2873    }
2874
2875    /**
2876     * Sets the organizational unit name.<p>
2877     *
2878     * @param orgUnitName the name to set
2879     */
2880    public void setOrgUnitName(String orgUnitName) {
2881
2882        m_orgUnitName = orgUnitName;
2883    }
2884
2885    /**
2886     * Sets the project Description.<p>
2887     *
2888     * @param projectDescription the description to set
2889     */
2890    public void setProjectDescription(String projectDescription) {
2891
2892        m_projectDescription = projectDescription;
2893    }
2894
2895    /**
2896     * Sets the project Managers group name.<p>
2897     *
2898     * @param projectManagers the managers group to set
2899     */
2900    public void setProjectManagers(String projectManagers) {
2901
2902        m_projectManagers = projectManagers;
2903    }
2904
2905    /**
2906     * Sets the project Name.<p>
2907     *
2908     * @param projectName the name to set
2909     */
2910    public void setProjectName(String projectName) {
2911
2912        m_projectName = projectName;
2913    }
2914
2915    /**
2916     * Sets the project Users group name.<p>
2917     *
2918     * @param projectUsers the Users group to set
2919     */
2920    public void setProjectUsers(String projectUsers) {
2921
2922        m_projectUsers = projectUsers;
2923    }
2924
2925    /**
2926     * Sets the propertyName.<p>
2927     *
2928     * @param propertyName the propertyName to set
2929     *
2930     * @see #N_NAME
2931     * @see #addResourcePropertyRules(Digester, String)
2932     */
2933    public void setPropertyName(String propertyName) {
2934
2935        m_propertyName = propertyName;
2936    }
2937
2938    /**
2939     * Sets the propertyValue.<p>
2940     *
2941     * @param propertyValue the propertyValue to set
2942     *
2943     * @see #N_VALUE
2944     * @see #addResourcePropertyRules(Digester, String)
2945     */
2946    public void setPropertyValue(String propertyValue) {
2947
2948        m_propertyValue = propertyValue;
2949    }
2950
2951    /**
2952     * Sets the relationId.<p>
2953     *
2954     * @param relationId the relationId to set
2955     *
2956     * @see #N_ID
2957     * @see #addResourceRelationRules(Digester, String)
2958     */
2959    public void setRelationId(String relationId) {
2960
2961        try {
2962            m_relationId = new CmsUUID(relationId);
2963        } catch (Throwable e) {
2964            setThrowable(e);
2965        }
2966    }
2967
2968    /**
2969     * Sets the relationPath.<p>
2970     *
2971     * @param relationPath the relationPath to set
2972     *
2973     * @see #N_PATH
2974     * @see #addResourceRelationRules(Digester, String)
2975     */
2976    public void setRelationPath(String relationPath) {
2977
2978        m_relationPath = relationPath;
2979    }
2980
2981    /**
2982     * Sets the relationType.<p>
2983     *
2984     * @param relationType the relationType to set
2985     *
2986     * @see #N_TYPE
2987     * @see #addResourceRelationRules(Digester, String)
2988     */
2989    public void setRelationType(String relationType) {
2990
2991        try {
2992            m_relationType = CmsRelationType.valueOf(relationType);
2993        } catch (Throwable e) {
2994            setThrowable(e);
2995        }
2996    }
2997
2998    /**
2999     * Sets the resourceId.<p>
3000     *
3001     * @param resourceId the resourceId to set
3002     *
3003     * @see #N_UUIDRESOURCE
3004     * @see #addResourceAttributesRules(Digester, String)
3005     */
3006    public void setResourceId(String resourceId) {
3007
3008        try {
3009            if (!m_resourceBuilder.isFolder()) {
3010                m_resourceBuilder.setResourceId(new CmsUUID(resourceId));
3011            } else {
3012                m_resourceBuilder.setResourceId(new CmsUUID());
3013            }
3014        } catch (Throwable e) {
3015            setThrowable(e);
3016        }
3017    }
3018
3019    /**
3020     * Sets the source.<p>
3021     *
3022     * @param source the source to set
3023     *
3024     * @see #N_SOURCE
3025     * @see #addResourceAttributesRules(Digester, String)
3026     */
3027    public void setSource(String source) {
3028
3029        m_source = source;
3030    }
3031
3032    /**
3033     * Sets the structureId.<p>
3034     *
3035     * @param structureId the structureId to set
3036     *
3037     * @see #N_UUIDSTRUCTURE
3038     * @see #addResourceAttributesRules(Digester, String)
3039     */
3040    public void setStructureId(String structureId) {
3041
3042        try {
3043            m_resourceBuilder.setStructureId(new CmsUUID(structureId));
3044            m_hasStructureId = true;
3045
3046        } catch (Throwable e) {
3047            setThrowable(e);
3048        }
3049
3050    }
3051
3052    /**
3053     * Sets the throwable.<p>
3054     *
3055     * @param throwable the throwable to set
3056     */
3057    public void setThrowable(Throwable throwable) {
3058
3059        m_throwable = throwable;
3060    }
3061
3062    /**
3063     * Sets the type.<p>
3064     *
3065     * @param typeName the type to set
3066     *
3067     * @see #N_TYPE
3068     * @see #addResourceAttributesRules(Digester, String)
3069     */
3070    public void setType(String typeName) {
3071
3072        m_typeName = typeName;
3073        try {
3074            try {
3075                m_resourceBuilder.setType(OpenCms.getResourceManager().getResourceType(typeName));
3076            } catch (@SuppressWarnings("unused") CmsLoaderException e) {
3077                m_unknownType = true;
3078                // TODO: what happens if the resource type is a specialized folder and is not configured??
3079                try {
3080                    m_resourceBuilder.setType(
3081                        OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()));
3082                } catch (@SuppressWarnings("unused") CmsLoaderException e1) {
3083                    // this should really never happen
3084                    m_resourceBuilder.setType(
3085                        OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()));
3086                }
3087            }
3088            if (m_resourceBuilder.getType().isFolder()) {
3089                // ensure folders end with a "/"
3090                if (!CmsResource.isFolder(m_destination)) {
3091                    m_destination += "/";
3092                }
3093            }
3094        } catch (Throwable e) {
3095            setThrowable(e);
3096        }
3097    }
3098
3099    /**
3100     * Sets the user Created.<p>
3101     *
3102     * @param userCreated the user Created to set
3103     */
3104    public void setUserCreated(CmsUUID userCreated) {
3105
3106        m_resourceBuilder.setUserCreated(userCreated);
3107    }
3108
3109    /**
3110     * Sets the userCreated.<p>
3111     *
3112     * @param userCreated the userCreated to set
3113     *
3114     * @see #N_USERCREATED
3115     * @see #addResourceAttributesRules(Digester, String)
3116     */
3117    public void setUserCreated(String userCreated) {
3118
3119        try {
3120            String userCreatedName = OpenCms.getImportExportManager().translateUser(userCreated);
3121            try {
3122                m_resourceBuilder.setUserCreated(getCms().readUser(userCreatedName).getId());
3123            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
3124                m_resourceBuilder.setUserCreated(getRequestContext().getCurrentUser().getId());
3125            }
3126        } catch (Throwable e) {
3127            setThrowable(e);
3128        }
3129    }
3130
3131    /**
3132     * Sets the user Date Created.<p>
3133     *
3134     * @param userDateCreated the date to set
3135     */
3136    public void setUserDateCreated(String userDateCreated) {
3137
3138        try {
3139            m_userDateCreated = convertTimestamp(userDateCreated);
3140        } catch (Throwable e) {
3141            setThrowable(e);
3142        }
3143    }
3144
3145    /**
3146     * Sets the user email address.<p>
3147     *
3148     * @param userEmail the email address to set
3149     */
3150    public void setUserEmail(String userEmail) {
3151
3152        m_userEmail = userEmail;
3153    }
3154
3155    /**
3156     * Sets the user First name.<p>
3157     *
3158     * @param userFirstname the first name to set
3159     */
3160    public void setUserFirstname(String userFirstname) {
3161
3162        m_userFirstname = userFirstname;
3163    }
3164
3165    /**
3166     * Sets the user Flags.<p>
3167     *
3168     * @param userFlags the flags to set
3169     */
3170    public void setUserFlags(String userFlags) {
3171
3172        try {
3173            m_userFlags = Integer.parseInt(userFlags);
3174        } catch (Throwable e) {
3175            setThrowable(e);
3176        }
3177    }
3178
3179    /**
3180     * Sets the user Last Modified.<p>
3181     *
3182     * @param userLastModified the user Last Modified to set
3183     */
3184    public void setUserLastModified(CmsUUID userLastModified) {
3185
3186        m_resourceBuilder.setUserLastModified(userLastModified);
3187    }
3188
3189    /**
3190     * Sets the userLastModified.<p>
3191     *
3192     * @param userLastModified the userLastModified to set
3193     *
3194     * @see #N_USERLASTMODIFIED
3195     * @see #addResourceAttributesRules(Digester, String)
3196     */
3197    public void setUserLastModified(String userLastModified) {
3198
3199        if (null == userLastModified) { // The optional user last modified information is not provided
3200            m_resourceBuilder.setUserLastModified(getRequestContext().getCurrentUser().getId());
3201        } else { // use the user last modified information from the manifest
3202            try {
3203                String userLastModifiedName = OpenCms.getImportExportManager().translateUser(userLastModified);
3204                try {
3205                    m_resourceBuilder.setUserLastModified(getCms().readUser(userLastModifiedName).getId());
3206                } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
3207                    m_resourceBuilder.setUserLastModified(getRequestContext().getCurrentUser().getId());
3208                }
3209            } catch (Throwable e) {
3210                setThrowable(e);
3211            }
3212        }
3213
3214    }
3215
3216    /**
3217     * Sets the user Last name.<p>
3218     *
3219     * @param userLastname the last name to set
3220     */
3221    public void setUserLastname(String userLastname) {
3222
3223        m_userLastname = userLastname;
3224    }
3225
3226    /**
3227     * Sets the user Name.<p>
3228     *
3229     * @param userName the name to set
3230     */
3231    public void setUserName(String userName) {
3232
3233        m_userName = OpenCms.getImportExportManager().translateUser(userName);
3234    }
3235
3236    /**
3237     * Sets the user Password.<p>
3238     *
3239     * @param userPassword the password to set
3240     */
3241    public void setUserPassword(String userPassword) {
3242
3243        m_userPassword = new String(Base64.decodeBase64(userPassword.trim().getBytes()));
3244    }
3245
3246    /**
3247     * Sets the export version from the manifest file.<p>
3248     *
3249     * @param version the export version to set
3250     */
3251    public void setVersion(String version) {
3252
3253        m_version = Integer.parseInt(version);
3254    }
3255
3256    /**
3257     * Adds the XML digester rules for groups.<p>
3258     *
3259     * @param digester the digester to add the rules to
3260     * @param xpath the base xpath for the rules
3261     */
3262    protected void addAccountsGroupRules(Digester digester, String xpath) {
3263
3264        String xp_group = xpath + N_GROUPS + "/" + N_GROUP;
3265        digester.addCallMethod(xp_group, "importGroup");
3266        xp_group += "/";
3267        digester.addCallMethod(xp_group + N_NAME, "setGroupName", 0);
3268        digester.addCallMethod(xp_group + N_DESCRIPTION, "setGroupDescription", 0);
3269        digester.addCallMethod(xp_group + N_FLAGS, "setGroupFlags", 0);
3270        digester.addCallMethod(xp_group + N_PARENTGROUP, "setGroupParent", 0);
3271    }
3272
3273    /**
3274     * Adds the XML digester rules for organizational units.<p>
3275     *
3276     * @param digester the digester to add the rules to
3277     * @param xpath the base xpath for the rules
3278     */
3279    protected void addAccountsOrgunitRules(Digester digester, String xpath) {
3280
3281        digester.addCallMethod(xpath + N_NAME, "setOrgUnitName", 0);
3282        digester.addCallMethod(xpath + N_DESCRIPTION, "setOrgUnitDescription", 0);
3283        digester.addCallMethod(xpath + N_FLAGS, "setOrgUnitFlags", 0);
3284        digester.addCallMethod(xpath + N_RESOURCES + "/" + N_RESOURCE, "addOrgUnitResource", 0);
3285        digester.addCallMethod(xpath + N_RESOURCES, "importOrgUnit");
3286    }
3287
3288    /**
3289     * Adds the XML digester rules for users.<p>
3290     *
3291     * @param digester the digester to add the rules to
3292     * @param xpath the base xpath for the rules
3293     */
3294    protected void addAccountsUserRules(Digester digester, String xpath) {
3295
3296        String xp_user = xpath + N_USERS + "/" + N_USER + "/";
3297        digester.addCallMethod(xp_user + N_NAME, "setUserName", 0);
3298        digester.addCallMethod(xp_user + N_PASSWORD, "setUserPassword", 0);
3299        digester.addCallMethod(xp_user + N_FIRSTNAME, "setUserFirstname", 0);
3300        digester.addCallMethod(xp_user + N_LASTNAME, "setUserLastname", 0);
3301        digester.addCallMethod(xp_user + N_EMAIL, "setUserEmail", 0);
3302        digester.addCallMethod(xp_user + N_FLAGS, "setUserFlags", 0);
3303        digester.addCallMethod(xp_user + N_DATECREATED, "setUserDateCreated", 0);
3304        digester.addCallMethod(xp_user + N_USERINFO, "importUser");
3305
3306        String xp_info = xp_user + N_USERINFO + "/" + N_USERINFO_ENTRY;
3307        digester.addCallMethod(xp_info, "importUserInfo", 3);
3308        digester.addCallParam(xp_info, 0, A_NAME);
3309        digester.addCallParam(xp_info, 1, A_TYPE);
3310        digester.addCallParam(xp_info, 2);
3311
3312        digester.addCallMethod(xp_user + N_USERROLES + "/" + N_USERROLE, "importUserRole", 0);
3313        digester.addCallMethod(xp_user + N_USERGROUPS + "/" + N_USERGROUP, "importUserGroup", 0);
3314    }
3315
3316    /**
3317     * Adds the XML digester rules for projects.<p>
3318     *
3319     * @param digester the digester to add the rules to
3320     * @param xpath the base xpath for the rules
3321     */
3322    protected void addProjectRules(Digester digester, String xpath) {
3323
3324        digester.addCallMethod(xpath + N_NAME, "setProjectName", 0);
3325        digester.addCallMethod(xpath + N_DESCRIPTION, "setProjectDescription", 0);
3326        digester.addCallMethod(xpath + N_MANAGERSGROUP, "setProjectManagers", 0);
3327        digester.addCallMethod(xpath + N_USERSGROUP, "setProjectUsers", 0);
3328        digester.addCallMethod(xpath + N_RESOURCES + "/" + N_RESOURCE, "addProjectResource", 0);
3329        digester.addCallMethod(xpath + N_RESOURCES, "importProject");
3330    }
3331
3332    /**
3333     * Adds the XML digester rules for resource access control entries.<p>
3334     *
3335     * @param digester the digester to add the rules to
3336     * @param xpath the base xpath for the rules
3337     */
3338    protected void addResourceAceRules(Digester digester, String xpath) {
3339
3340        String xp_ace = xpath + N_ACCESSCONTROL_ENTRIES + "/" + N_ACCESSCONTROL_ENTRY;
3341        digester.addCallMethod(xp_ace, "addAccessControlEntry");
3342        digester.addCallMethod(xp_ace + "/" + N_ACCESSCONTROL_PRINCIPAL, "setAcePrincipalId", 0);
3343        digester.addCallMethod(xp_ace + "/" + N_FLAGS, "setAceFlags", 0);
3344        String xp_perms = xp_ace + "/" + N_ACCESSCONTROL_PERMISSIONSET + "/";
3345        digester.addCallMethod(xp_perms + N_ACCESSCONTROL_ALLOWEDPERMISSIONS, "setAcePermissionsAllowed", 0);
3346        digester.addCallMethod(xp_perms + N_ACCESSCONTROL_DENIEDPERMISSIONS, "setAcePermissionsDenied", 0);
3347    }
3348
3349    /**
3350     * Adds the XML digester rules for resource attributes.<p>
3351     *
3352     * @param digester the digester to add the rules to
3353     * @param xpath the base xpath for the rules
3354     */
3355    protected void addResourceAttributesRules(Digester digester, String xpath) {
3356
3357        digester.addCallMethod(xpath + N_SOURCE, "setSource", 0);
3358        digester.addCallMethod(xpath + N_DESTINATION, "setDestination", 0);
3359        digester.addCallMethod(xpath + N_TYPE, "setType", 0);
3360        digester.addCallMethod(xpath + N_UUIDSTRUCTURE, "setStructureId", 0);
3361        digester.addCallMethod(xpath + N_UUIDRESOURCE, "setResourceId", 0);
3362        digester.addCallMethod(xpath + N_DATELASTMODIFIED, "setDateLastModified", 0);
3363        digester.addCallMethod(xpath + N_USERLASTMODIFIED, "setUserLastModified", 0);
3364        digester.addCallMethod(xpath + N_DATECREATED, "setDateCreated", 0);
3365        digester.addCallMethod(xpath + N_USERCREATED, "setUserCreated", 0);
3366        digester.addCallMethod(xpath + N_DATERELEASED, "setDateReleased", 0);
3367        digester.addCallMethod(xpath + N_DATEEXPIRED, "setDateExpired", 0);
3368        digester.addCallMethod(xpath + N_FLAGS, "setFlags", 0);
3369    }
3370
3371    /**
3372     * Adds the XML digester rules for resource properties.<p>
3373     *
3374     * @param digester the digester to add the rules to
3375     * @param xpath the base xpath for the rules
3376     */
3377    protected void addResourcePropertyRules(Digester digester, String xpath) {
3378
3379        String xp_props = xpath + N_PROPERTIES + "/" + N_PROPERTY;
3380        // first rule in case the type is implicit
3381        digester.addCallMethod(xp_props, "addProperty");
3382        // second rule in case the type is given
3383        digester.addCallMethod(xp_props, "addProperty", 1);
3384        digester.addCallParam(xp_props, 0, A_TYPE);
3385
3386        digester.addCallMethod(xp_props + "/" + N_NAME, "setPropertyName", 0);
3387        digester.addCallMethod(xp_props + "/" + N_VALUE, "setPropertyValue", 0);
3388
3389    }
3390
3391    /**
3392     * Adds the XML digester rules for resource relations.<p>
3393     *
3394     * @param digester the digester to add the rules to
3395     * @param xpath the base xpath for the rules
3396     */
3397    protected void addResourceRelationRules(Digester digester, String xpath) {
3398
3399        String xp_rels = xpath + N_RELATIONS + "/" + N_RELATION;
3400        digester.addCallMethod(xp_rels, "addRelation");
3401        digester.addCallMethod(xp_rels + "/" + N_ID, "setRelationId", 0);
3402        digester.addCallMethod(xp_rels + "/" + N_PATH, "setRelationPath", 0);
3403        digester.addCallMethod(xp_rels + "/" + N_TYPE, "setRelationType", 0);
3404    }
3405
3406    /**
3407     * Checks if the resources is in the list of immutable resources.<p>
3408     *
3409     * @param resourceName the name of the resource
3410     *
3411     * @return <code>true</code> or <code>false</code>
3412     */
3413    protected boolean checkImmutable(String resourceName) {
3414
3415        boolean resourceImmutable = false;
3416        if (getImmutableResources().contains(resourceName)) {
3417            if (LOG.isDebugEnabled()) {
3418                LOG.debug(
3419                    Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_RESOURCENAME_IMMUTABLE_1, resourceName));
3420            }
3421            // this resource must not be modified by an import if it already exists
3422            String storedSiteRoot = getRequestContext().getSiteRoot();
3423            try {
3424                getRequestContext().setSiteRoot("/");
3425                getCms().readResource(resourceName);
3426                resourceImmutable = true;
3427                if (LOG.isDebugEnabled()) {
3428                    LOG.debug(
3429                        Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_IMMUTABLE_FLAG_SET_1, resourceName));
3430                }
3431            } catch (CmsException e) {
3432                // resourceNotImmutable will be true
3433                if (LOG.isDebugEnabled()) {
3434                    LOG.debug(
3435                        Messages.get().getBundle().key(
3436                            Messages.LOG_IMPORTEXPORT_ERROR_ON_TEST_IMMUTABLE_1,
3437                            resourceName),
3438                        e);
3439                }
3440            } finally {
3441                getRequestContext().setSiteRoot(storedSiteRoot);
3442            }
3443        }
3444        return resourceImmutable;
3445    }
3446
3447    /**
3448     * Converts a given digest to base64 encoding.<p>
3449     *
3450     * @param value the digest value in the legacy encoding
3451     *
3452     * @return the digest in the new encoding
3453     */
3454    protected String convertDigestEncoding(String value) {
3455
3456        byte[] data = new byte[value.length() / 2];
3457
3458        for (int i = 0; i < data.length; i++) {
3459            data[i] = (byte)(Integer.parseInt(value.substring(i * 2, (i * 2) + 2), 16) - 128);
3460        }
3461        return new String(Base64.encodeBase64(data));
3462    }
3463
3464    /**
3465     * Convert a given time stamp from a String format to a long value.<p>
3466     *
3467     * The time stamp is either the string representation of a long value (old export format)
3468     * or a user-readable string format.<p>
3469     *
3470     * @param timestamp time stamp to convert
3471     *
3472     * @return long value of the time stamp
3473     */
3474    protected long convertTimestamp(String timestamp) {
3475
3476        long value = 0;
3477        // try to parse the time stamp string
3478        // if it successes, its an old style long value
3479        try {
3480            value = Long.parseLong(timestamp);
3481        } catch (@SuppressWarnings("unused") NumberFormatException e) {
3482            // the time stamp was in in a user-readable string format, create the long value form it
3483            try {
3484                value = CmsDateUtil.parseHeaderDate(timestamp);
3485            } catch (@SuppressWarnings("unused") ParseException pe) {
3486                value = System.currentTimeMillis();
3487            }
3488        }
3489        return value;
3490    }
3491
3492    /**
3493     * Create a CmsResource object from the currently set field values.<p>
3494     *
3495     * @param translatedName the resource name
3496     * @param size the size
3497     * @return the new CmsResource object
3498     */
3499    protected CmsResource createResourceObjectFromFields(String translatedName, int size) {
3500
3501        m_resourceBuilder.setRootPath(translatedName);
3502        m_resourceBuilder.setState(CmsResource.STATE_NEW);
3503        m_resourceBuilder.setProjectLastModified(getRequestContext().getCurrentProject().getUuid());
3504        m_resourceBuilder.setLength(size);
3505        m_resourceBuilder.setSiblingCount(1);
3506        m_resourceBuilder.setVersion(0);
3507        m_resourceBuilder.setDateContent(System.currentTimeMillis());
3508        return m_resourceBuilder.buildResource();
3509    }
3510
3511    /**
3512     * This method goes through the manifest, records all files from the manifest for which the content also
3513     * exists in the zip file, and stores their resource ids in m_contentFiles.<p>
3514     *
3515     * @throws CmsImportExportException thrown when the manifest.xml can't be opened as stream.
3516     * @throws IOException thrown if the manifest.xml stream causes problems during parsing and/or closing.
3517     * @throws SAXException thrown if parsing the manifest.xml fails
3518     */
3519    protected void findContentFiles() throws CmsImportExportException, IOException, SAXException {
3520
3521        Digester digester = new Digester();
3522        digester.setUseContextClassLoader(true);
3523        digester.setValidating(false);
3524        digester.setEntityResolver(new CmsXmlEntityResolver(null));
3525        digester.setRuleNamespaceURI(null);
3526        digester.setErrorHandler(new CmsXmlErrorHandler(CmsImportExportManager.EXPORT_MANIFEST));
3527
3528        digester.addCallMethod("export/files/file", "addContentFile", 2);
3529        digester.addCallParam("export/files/file/source", 0);
3530        digester.addCallParam("export/files/file/uuidresource", 1);
3531        m_contentFiles.clear();
3532        digester.push(this);
3533        InputStream stream = null;
3534        try {
3535            stream = m_helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
3536            digester.parse(stream);
3537        } finally {
3538            if (stream != null) {
3539                stream.close();
3540            }
3541        }
3542    }
3543
3544    /**
3545     * Gets the import helper instance.<p>
3546     *
3547     * @return the import helper
3548     */
3549    protected CmsImportHelper getHelper() {
3550
3551        return m_helper;
3552    }
3553
3554    /**
3555     * Returns the list of properties to ignore during import.<p>
3556     *
3557     * @return the list of properties to ignore during import
3558     */
3559    protected List<String> getIgnoredProperties() {
3560
3561        if (m_ignoredProperties == null) {
3562            // get list of ignored properties
3563            m_ignoredProperties = OpenCms.getImportExportManager().getIgnoredProperties();
3564            if (m_ignoredProperties == null) {
3565                m_ignoredProperties = Collections.emptyList();
3566            }
3567        }
3568        return m_ignoredProperties;
3569    }
3570
3571    /**
3572     * Returns the list of immutable resources.<p>
3573     *
3574     * @return the list of immutable resources
3575     */
3576    protected List<String> getImmutableResources() {
3577
3578        if (m_immutables == null) {
3579            // get list of immutable resources
3580            m_immutables = OpenCms.getImportExportManager().getImmutableResources();
3581            if (m_immutables == null) {
3582                m_immutables = Collections.emptyList();
3583            }
3584            if (LOG.isDebugEnabled()) {
3585                LOG.debug(
3586                    Messages.get().getBundle().key(
3587                        Messages.LOG_IMPORTEXPORT_IMMUTABLE_RESOURCES_SIZE_1,
3588                        Integer.toString(m_immutables.size())));
3589            }
3590        }
3591        return m_immutables;
3592    }
3593
3594    /**
3595     * Checks if the given type name refers to a folder type.
3596     *
3597     * @param typeName the type name
3598     * @return the type name
3599     */
3600    protected boolean isFolderType(String typeName) {
3601        if (OpenCms.getResourceManager().hasResourceType(typeName)) {
3602            try {
3603                return OpenCms.getResourceManager().getResourceType(typeName).isFolder();
3604            } catch (CmsLoaderException e) {
3605                LOG.error(e.getLocalizedMessage(), e);
3606            }
3607        }
3608        return false;
3609    }
3610
3611    /**
3612     * Fills the unset fields for an imported resource with default values.<p>
3613     *
3614     * @throws CmsImportExportException if something goes wrong
3615     */
3616    protected void setDefaultsForEmptyResourceFields() throws CmsImportExportException {
3617
3618        // get UUID for the structure
3619        if (m_resourceBuilder.getStructureId() == null) {
3620            // if null generate a new structure id
3621            m_resourceBuilder.setStructureId(new CmsUUID());
3622        }
3623
3624        if ((m_resourceBuilder.getResourceId() == null) && m_unknownType) {
3625            try {
3626                m_resourceBuilder.setType(OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName()));
3627            } catch (CmsLoaderException e) {
3628                LOG.error(e.getLocalizedMessage(), e);
3629            }
3630        }
3631        if (m_resourceBuilder.getType().isFolder()) {
3632            // ensure folders end with a "/"
3633            if (!CmsResource.isFolder(m_destination)) {
3634                m_destination += "/";
3635            }
3636        }
3637
3638        // get UUIDs for the resource
3639        if ((m_resourceBuilder.getResourceId() == null) || (m_resourceBuilder.getType().isFolder())) {
3640            // folders get always a new resource UUID
3641            m_resourceBuilder.setResourceId(new CmsUUID());
3642            m_resourceIdWasNull = true;
3643        }
3644
3645        // read date last modified from the resource, default to currentTime for folders
3646        if (m_resourceBuilder.getDateLastModified() == DATE_LAST_MODIFICATION_FILETIME) {
3647            if (null != m_source) {
3648                m_resourceBuilder.setDateLastModified(m_helper.getFileModification(m_source));
3649            } else {
3650                m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
3651            }
3652        }
3653
3654        if (m_resourceBuilder.getDateLastModified() == DATE_LAST_MODIFICATION_UNSPECIFIED) {
3655            m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
3656        }
3657
3658        if (null == m_resourceBuilder.getUserLastModified()) {
3659            m_resourceBuilder.setUserLastModified(m_cms.getRequestContext().getCurrentUser().getId());
3660        }
3661
3662        if (m_resourceBuilder.getDateCreated() == DATE_CREATED_UNSPECIFIED) {
3663            m_resourceBuilder.setDateCreated(System.currentTimeMillis());
3664        }
3665
3666        if (m_resourceBuilder.getUserCreated().isNullUUID()) {
3667            m_resourceBuilder.setUserCreated(getRequestContext().getCurrentUser().getId());
3668        }
3669
3670        if (m_properties == null) {
3671            m_properties = new HashMap<String, CmsProperty>();
3672        }
3673    }
3674
3675    /**
3676     * Checks whether the content for the resource being imported exists either in the VFS or in the import file.<p>
3677     *
3678     * @param resource the resource which should be checked
3679     *
3680     * @return true if the content exists in the VFS or import file
3681     */
3682    private boolean hasContentInVfsOrImport(CmsResource resource) {
3683
3684        if (m_contentFiles.contains(resource.getResourceId())) {
3685            return true;
3686        }
3687        try {
3688            List<CmsResource> resources = getCms().readSiblings(resource, CmsResourceFilter.ALL);
3689            if (!resources.isEmpty()) {
3690                return true;
3691            }
3692        } catch (CmsException e) {
3693            LOG.warn(e.getLocalizedMessage(), e);
3694        }
3695        return false;
3696
3697    }
3698}