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 resourceImmutable = checkImmutable(translatedName);
2063            translatedName = getRequestContext().removeSiteRoot(translatedName);
2064            // if the resource is not immutable and not on the exclude list, import it
2065            if (!resourceImmutable) {
2066                // print out the information to the report
2067                getReport().print(Messages.get().container(Messages.RPT_IMPORTING_0), I_CmsReport.FORMAT_NOTE);
2068                getReport().print(
2069                    org.opencms.report.Messages.get().container(
2070                        org.opencms.report.Messages.RPT_ARGUMENT_1,
2071                        translatedName));
2072                getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
2073
2074                boolean exists = getCms().existsResource(translatedName, CmsResourceFilter.ALL);
2075
2076                byte[] content = null;
2077                // get the file content
2078
2079                if (m_source != null) {
2080                    content = m_helper.getFileBytes(m_source);
2081                }
2082                int size = 0;
2083                if (content != null) {
2084                    size = content.length;
2085                }
2086                setDefaultsForEmptyResourceFields();
2087                // create a new CmsResource
2088                CmsResource resource = createResourceObjectFromFields(translatedName, size);
2089                if (!OpenCms.getResourceManager().hasResourceType(m_typeName)) {
2090                    m_properties.put(
2091                        CmsPropertyDefinition.PROPERTY_EXPORT_TYPE,
2092                        new CmsProperty(CmsPropertyDefinition.PROPERTY_EXPORT_TYPE, null, m_typeName, true));
2093                }
2094                if (m_resourceBuilder.getType().isFolder()
2095                    || m_resourceIdWasNull
2096                    || hasContentInVfsOrImport(resource)) {
2097                    // import this resource in the VFS
2098                    m_resource = getCms().importResource(
2099                        translatedName,
2100                        getReport(),
2101                        resource,
2102                        content,
2103                        new ArrayList<CmsProperty>(m_properties.values()));
2104                }
2105
2106                if (m_resource != null) {
2107                    m_indexToStructureId.put(Integer.valueOf(m_fileCounter), m_resource.getStructureId());
2108                }
2109
2110                // only set permissions if the resource did not exists or if the keep permissions flag is not set
2111                m_importACEs = (m_resource != null) && (!exists || !m_parameters.isKeepPermissions());
2112
2113                if (m_resource != null) {
2114                    getReport().println(
2115                        org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
2116                        I_CmsReport.FORMAT_OK);
2117
2118                    if (OpenCms.getResourceManager().getResourceType(
2119                        m_resource.getTypeId()) instanceof I_CmsLinkParseable) {
2120                        // store for later use
2121                        m_parseables.add(m_resource);
2122                    }
2123                    if (LOG.isInfoEnabled()) {
2124                        LOG.info(
2125                            Messages.get().getBundle().key(
2126                                Messages.LOG_IMPORTING_4,
2127                                new Object[] {
2128                                    String.valueOf(m_fileCounter),
2129                                    String.valueOf(m_totalFiles),
2130                                    translatedName,
2131                                    m_destination}));
2132                    }
2133                } else {
2134                    // resource import failed, since no CmsResource was created
2135                    getReport().print(Messages.get().container(Messages.RPT_SKIPPING_0), I_CmsReport.FORMAT_NOTE);
2136                    getReport().println(
2137                        org.opencms.report.Messages.get().container(
2138                            org.opencms.report.Messages.RPT_ARGUMENT_1,
2139                            translatedName));
2140
2141                    if (LOG.isInfoEnabled()) {
2142                        LOG.info(
2143                            Messages.get().getBundle().key(
2144                                Messages.LOG_SKIPPING_3,
2145                                String.valueOf(m_fileCounter),
2146                                String.valueOf(m_totalFiles),
2147                                translatedName));
2148                    }
2149                }
2150            } else {
2151                m_resource = null;
2152                // skip the file import, just print out the information to the report
2153                getReport().print(Messages.get().container(Messages.RPT_SKIPPING_0), I_CmsReport.FORMAT_NOTE);
2154                getReport().println(
2155                    org.opencms.report.Messages.get().container(
2156                        org.opencms.report.Messages.RPT_ARGUMENT_1,
2157                        translatedName));
2158
2159                if (LOG.isInfoEnabled()) {
2160                    LOG.info(
2161                        Messages.get().getBundle().key(
2162                            Messages.LOG_SKIPPING_3,
2163                            String.valueOf(m_fileCounter),
2164                            String.valueOf(m_totalFiles),
2165                            translatedName));
2166                }
2167                // do not import ACEs
2168                m_importACEs = false;
2169            }
2170        } catch (Exception e) {
2171            m_resource = null;
2172            m_importACEs = false;
2173
2174            getReport().println(e);
2175            getReport().addError(e);
2176
2177            CmsMessageContainer message = Messages.get().container(
2178                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_RESOURCES_0);
2179            if (LOG.isDebugEnabled()) {
2180                LOG.debug(message.key(), e);
2181            }
2182
2183            return;
2184        }
2185    }
2186
2187    /**
2188     * Imports the resource and access control entries.<p>
2189     */
2190    public void importResourceAll() {
2191
2192        try {
2193            importResource();
2194            importAccessControlEntries();
2195            increaseCounter();
2196        } finally {
2197            m_destination = null;
2198            m_source = null;
2199            m_throwable = null;
2200            m_properties = null;
2201            m_aces = null;
2202        }
2203    }
2204
2205    /**
2206     * @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)
2207     *
2208     * @deprecated use {@link #importData(CmsObject, I_CmsReport, CmsImportParameters)} instead
2209     */
2210    @Deprecated
2211    public void importResources(
2212        CmsObject cms,
2213        String importPath,
2214        I_CmsReport report,
2215        File importResource,
2216        ZipFile importZip,
2217        Document docXml) {
2218
2219        CmsImportParameters params = new CmsImportParameters(importResource.getAbsolutePath(), importPath, true);
2220
2221        importData(cms, report, params);
2222    }
2223
2224    /**
2225     * Imports a new user from the current xml data.<p>
2226     */
2227    public void importUser() {
2228
2229        // create a new user id
2230        String userName = m_orgUnit.getName() + m_userName;
2231        try {
2232            if (m_throwable != null) {
2233                m_user = null;
2234                getReport().println(m_throwable);
2235
2236                CmsMessageContainer message = Messages.get().container(
2237                    Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USER_1,
2238                    userName);
2239                if (LOG.isDebugEnabled()) {
2240                    LOG.debug(message.key(), m_throwable);
2241                }
2242                m_throwable = null;
2243                return;
2244            }
2245
2246            getReport().print(Messages.get().container(Messages.RPT_IMPORT_USER_0), I_CmsReport.FORMAT_NOTE);
2247            getReport().print(
2248                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_ARGUMENT_1, userName));
2249            getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
2250
2251            try {
2252                getCms().readUser(userName);
2253                // user exists already
2254                getReport().println(Messages.get().container(Messages.RPT_NOT_CREATED_0), I_CmsReport.FORMAT_OK);
2255                m_user = null;
2256                return;
2257            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2258                // user does not exist
2259            }
2260
2261            CmsParameterConfiguration config = OpenCms.getPasswordHandler().getConfiguration();
2262            if ((config != null) && config.containsKey(I_CmsPasswordHandler.CONVERT_DIGEST_ENCODING)) {
2263                if (config.getBoolean(I_CmsPasswordHandler.CONVERT_DIGEST_ENCODING, false)) {
2264                    m_userPassword = convertDigestEncoding(m_userPassword);
2265                }
2266            }
2267
2268            m_user = getCms().importUser(
2269                new CmsUUID().toString(),
2270                userName,
2271                m_userPassword,
2272                m_userFirstname,
2273                m_userLastname,
2274                m_userEmail,
2275                m_userFlags,
2276                m_userDateCreated,
2277                m_userInfos);
2278
2279            getReport().println(
2280                org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
2281                I_CmsReport.FORMAT_OK);
2282        } catch (Throwable e) {
2283            m_user = null;
2284            getReport().println(e);
2285
2286            CmsMessageContainer message = Messages.get().container(
2287                Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USER_1,
2288                userName);
2289            if (LOG.isDebugEnabled()) {
2290                LOG.debug(message.key(), e);
2291            }
2292        } finally {
2293            m_userName = null;
2294            m_userPassword = null;
2295            m_userFirstname = null;
2296            m_userLastname = null;
2297            m_userEmail = null;
2298            m_userFlags = 0;
2299            m_userDateCreated = 0;
2300            m_userInfos = null;
2301        }
2302    }
2303
2304    /**
2305     * Sets the current user as member of the given group.<p>
2306     *
2307     * It can happen that the organizational unit has not been imported jet,
2308     * in this case, the data is kept for later.<p>
2309     *
2310     * @param groupName the name of the group to set
2311     *
2312     * @see #setMembership()
2313     */
2314    public void importUserGroup(String groupName) {
2315
2316        if ((m_throwable != null) || (m_user == null)) {
2317            return;
2318        }
2319        groupName = OpenCms.getImportExportManager().translateGroup(groupName);
2320        try {
2321            String ouName = CmsOrganizationalUnit.getParentFqn(groupName);
2322            try {
2323                // check if the organizational unit exists
2324                OpenCms.getOrgUnitManager().readOrganizationalUnit(getCms(), ouName);
2325                // set the user group
2326                getCms().addUserToGroup(m_user.getName(), groupName);
2327                return;
2328            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2329                // organizational unit does not exist
2330            }
2331            // remember the user and group for later
2332            Map<String, Map<String, String>> membership = m_membership.get(ouName);
2333            if (membership == null) {
2334                membership = new HashMap<String, Map<String, String>>();
2335                m_membership.put(ouName, membership);
2336            }
2337            Map<String, String> groups = membership.get(I_CmsPrincipal.PRINCIPAL_GROUP);
2338            if (groups == null) {
2339                groups = new HashMap<String, String>();
2340                membership.put(I_CmsPrincipal.PRINCIPAL_GROUP, groups);
2341            }
2342            groups.put(m_user.getName(), groupName);
2343        } catch (Throwable e) {
2344            getReport().println(
2345                Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_GROUP_2, m_user.getName(), groupName),
2346                I_CmsReport.FORMAT_WARNING);
2347            if (LOG.isDebugEnabled()) {
2348                LOG.debug(e.getLocalizedMessage(), e);
2349            }
2350        }
2351    }
2352
2353    /**
2354     * Creates a new additional information entry for the current user.<p>
2355     *
2356     * @param infoName the name of the additional information entry
2357     * @param infoType the type of the additional information entry
2358     * @param infoValue the value of the additional information entry
2359     */
2360    public void importUserInfo(String infoName, String infoType, String infoValue) {
2361
2362        if (m_userInfos == null) {
2363            m_userInfos = new HashMap<String, Object>();
2364        }
2365        try {
2366            m_userInfos.put(infoName, CmsDataTypeUtil.dataImport(infoValue, infoType));
2367        } catch (Throwable e) {
2368            if (LOG.isErrorEnabled()) {
2369                LOG.error(e.getLocalizedMessage(), e);
2370            }
2371        }
2372    }
2373
2374    /**
2375     * Sets the current user as member of the given role.<p>
2376     *
2377     * It can happen that the organizational unit has not been imported jet,
2378     * in this case, the data is kept for later.<p>
2379     *
2380     * @param roleName the name of the role to set
2381     *
2382     * @see #setMembership()
2383     */
2384    public void importUserRole(String roleName) {
2385
2386        if ((m_throwable != null) || (m_user == null)) {
2387            return;
2388        }
2389        try {
2390            CmsRole role = CmsRole.valueOfRoleName(roleName);
2391            try {
2392                // check if the organizational unit exists
2393                OpenCms.getOrgUnitManager().readOrganizationalUnit(getCms(), role.getOuFqn());
2394                // set the user role
2395                OpenCms.getRoleManager().addUserToRole(getCms(), role, m_user.getName());
2396                return;
2397            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
2398                // organizational unit does not exist
2399            }
2400            // remember the user and role for later
2401            Map<String, Map<String, String>> membership = m_membership.get(role.getOuFqn());
2402            if (membership == null) {
2403                membership = new HashMap<String, Map<String, String>>();
2404                m_membership.put(role.getOuFqn(), membership);
2405            }
2406            Map<String, String> roles = membership.get(I_CmsPrincipal.PRINCIPAL_USER);
2407            if (roles == null) {
2408                roles = new HashMap<String, String>();
2409                membership.put(I_CmsPrincipal.PRINCIPAL_USER, roles);
2410            }
2411            roles.put(m_user.getName(), role.getFqn());
2412        } catch (Throwable e) {
2413            getReport().println(
2414                Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_ROLE_2, m_user.getName(), roleName),
2415                I_CmsReport.FORMAT_WARNING);
2416            if (LOG.isDebugEnabled()) {
2417                LOG.debug(e.getLocalizedMessage(), e);
2418            }
2419        }
2420    }
2421
2422    /**
2423     * Increases the file counter.<p>
2424     */
2425    public void increaseCounter() {
2426
2427        m_fileCounter++;
2428    }
2429
2430    /**
2431     * Increases the total number of files.<p>
2432     */
2433    public void increaseTotalFiles() {
2434
2435        m_totalFiles++;
2436    }
2437
2438    /**
2439     * @see org.opencms.importexport.I_CmsImport#matches(org.opencms.importexport.CmsImportParameters)
2440     */
2441    @SuppressWarnings("resource") //stream is closed always in finally block - don't know why the compiler complains
2442    public boolean matches(CmsImportParameters parameters) throws CmsImportExportException {
2443
2444        m_fileCounter = 1;
2445        m_totalFiles = 0;
2446        m_parseables = new ArrayList<CmsResource>();
2447
2448        m_parameters = parameters;
2449
2450        // instantiate Digester and enable XML validation
2451        Digester digester = new Digester();
2452        digester.setUseContextClassLoader(true);
2453        digester.setValidating(m_parameters.isXmlValidation());
2454        digester.setEntityResolver(new CmsXmlEntityResolver(null));
2455        digester.setRuleNamespaceURI(null);
2456        digester.setErrorHandler(new CmsXmlErrorHandler(CmsImportExportManager.EXPORT_MANIFEST));
2457
2458        // add this object to the Digester
2459        digester.push(this);
2460
2461        addXmlPreprocessingDigesterRules(digester);
2462
2463        InputStream stream = null;
2464        m_helper = new CmsImportHelper(m_parameters);
2465        m_helper.cacheDtdSystemId(DTD_LOCATION, DTD_FILENAME, CmsConfigurationManager.DEFAULT_DTD_PREFIX);
2466        try {
2467            m_helper.openFile();
2468            // start the parsing process
2469            // this will set the version attribute
2470            stream = m_helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
2471            digester.parse(stream);
2472        } catch (Exception ioe) {
2473            CmsMessageContainer msg = Messages.get().container(
2474                Messages.ERR_IMPORTEXPORT_ERROR_READING_FILE_1,
2475                CmsImportExportManager.EXPORT_MANIFEST);
2476            if (LOG.isErrorEnabled()) {
2477                LOG.error(msg.key(), ioe);
2478            }
2479            throw new CmsImportExportException(msg, ioe);
2480        } finally {
2481            try {
2482                if (stream != null) {
2483                    stream.close();
2484                }
2485            } catch (@SuppressWarnings("unused") Exception e) {
2486                // noop
2487            }
2488            m_helper.closeFile();
2489        }
2490        return (m_version == getVersion());
2491    }
2492
2493    /**
2494     * Rewrites all parseable files, to assure link check.<p>
2495     *
2496     * This is a global process, that is executed only once at the
2497     * end of the import to be sure that all link targets are
2498     * available.<p>
2499     *
2500     * @see #addXmlDigesterRules(Digester)
2501     */
2502    public void rewriteParseables() {
2503
2504        if (m_parseables.isEmpty()) {
2505            return;
2506        }
2507
2508        I_CmsReport report = getReport();
2509        CmsObject cms = getCms();
2510        cms.getRequestContext().setAttribute(CmsLogEntry.ATTR_LOG_ENTRY, Boolean.FALSE);
2511        report.println(Messages.get().container(Messages.RPT_START_PARSE_LINKS_0), I_CmsReport.FORMAT_HEADLINE);
2512        parseLinks(cms, m_parseables, report);
2513        report.println(Messages.get().container(Messages.RPT_END_PARSE_LINKS_0), I_CmsReport.FORMAT_HEADLINE);
2514        m_parseables = null;
2515    }
2516
2517    /**
2518     * Sets the aceFlags.<p>
2519     *
2520     * @param aceFlags the aceFlags to set
2521     *
2522     * @see #N_FLAGS
2523     * @see #addResourceAceRules(Digester, String)
2524     */
2525    public void setAceFlags(String aceFlags) {
2526
2527        try {
2528            m_aceFlags = Integer.parseInt(aceFlags);
2529        } catch (Throwable e) {
2530            m_throwable = e;
2531        }
2532    }
2533
2534    /**
2535     * Sets the acePermissionsAllowed.<p>
2536     *
2537     * @param acePermissionsAllowed the acePermissionsAllowed to set
2538     *
2539     * @see #N_ACCESSCONTROL_ALLOWEDPERMISSIONS
2540     * @see #addResourceAceRules(Digester, String)
2541     */
2542    public void setAcePermissionsAllowed(String acePermissionsAllowed) {
2543
2544        try {
2545            m_acePermissionsAllowed = Integer.parseInt(acePermissionsAllowed);
2546        } catch (Throwable e) {
2547            m_throwable = e;
2548        }
2549    }
2550
2551    /**
2552     * Sets the acePermissionsDenied.<p>
2553     *
2554     * @param acePermissionsDenied the acePermissionsDenied to set
2555     *
2556     * @see #N_ACCESSCONTROL_DENIEDPERMISSIONS
2557     * @see #addResourceAceRules(Digester, String)
2558     */
2559    public void setAcePermissionsDenied(String acePermissionsDenied) {
2560
2561        try {
2562            m_acePermissionsDenied = Integer.parseInt(acePermissionsDenied);
2563        } catch (Throwable e) {
2564            m_throwable = e;
2565        }
2566    }
2567
2568    /**
2569     * Sets the acePrincipalId.<p>
2570     *
2571     * @param acePrincipalId the acePrincipalId to set
2572     *
2573     * @see #N_ACCESSCONTROL_PRINCIPAL
2574     * @see #addResourceAceRules(Digester, String)
2575     */
2576    public void setAcePrincipalId(String acePrincipalId) {
2577
2578        try {
2579            CmsUUID principalId = null;
2580            String principal = acePrincipalId.substring(acePrincipalId.indexOf('.') + 1, acePrincipalId.length());
2581            if (acePrincipalId.startsWith(I_CmsPrincipal.PRINCIPAL_GROUP)) {
2582                principal = OpenCms.getImportExportManager().translateGroup(principal);
2583                principalId = getCms().readGroup(principal).getId();
2584            } else if (acePrincipalId.startsWith(I_CmsPrincipal.PRINCIPAL_USER)) {
2585                principal = OpenCms.getImportExportManager().translateUser(principal);
2586                principalId = getCms().readUser(principal).getId();
2587            } else if (acePrincipalId.startsWith(CmsRole.PRINCIPAL_ROLE)) {
2588                principalId = CmsRole.valueOfRoleName(principal).getId();
2589            } else if (acePrincipalId.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME)) {
2590                principalId = CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID;
2591            } else if (acePrincipalId.equalsIgnoreCase(CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME)) {
2592                principalId = CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID;
2593            } else {
2594                if (LOG.isWarnEnabled()) {
2595                    LOG.warn(
2596                        Messages.get().getBundle().key(
2597                            Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_ACE_1,
2598                            acePrincipalId));
2599                }
2600                throw new CmsIllegalStateException(
2601                    Messages.get().container(Messages.LOG_IMPORTEXPORT_ERROR_IMPORTING_ACE_1, acePrincipalId));
2602            }
2603            m_acePrincipalId = principalId;
2604        } catch (Throwable e) {
2605            setThrowable(e);
2606        }
2607    }
2608
2609    /**
2610     * Sets the dateCreated.<p>
2611     *
2612     * @param dateCreated the dateCreated to set
2613     *
2614     * @see #N_DATECREATED
2615     * @see #addResourceAttributesRules(Digester, String)
2616     */
2617    public void setDateCreated(String dateCreated) {
2618
2619        try {
2620            if (dateCreated != null) {
2621                m_resourceBuilder.setDateCreated(convertTimestamp(dateCreated));
2622            } else {
2623                m_resourceBuilder.setDateCreated(System.currentTimeMillis());
2624            }
2625        } catch (Throwable e) {
2626            setThrowable(e);
2627        }
2628    }
2629
2630    /**
2631     * Sets the dateExpired.<p>
2632     *
2633     * @param dateExpired the dateExpired to set
2634     *
2635     * @see #N_DATEEXPIRED
2636     * @see #addResourceAttributesRules(Digester, String)
2637     */
2638    public void setDateExpired(String dateExpired) {
2639
2640        try {
2641            if (dateExpired != null) {
2642                m_resourceBuilder.setDateExpired(convertTimestamp(dateExpired));
2643            } else {
2644                m_resourceBuilder.setDateExpired(CmsResource.DATE_EXPIRED_DEFAULT);
2645            }
2646        } catch (Throwable e) {
2647            setThrowable(e);
2648        }
2649    }
2650
2651    /**
2652     * Sets the dateLastModified.<p>
2653     *
2654     * @param dateLastModified the dateLastModified to set
2655     *
2656     * @see #N_DATELASTMODIFIED
2657     * @see #addResourceAttributesRules(Digester, String)
2658     */
2659    public void setDateLastModified(String dateLastModified) {
2660
2661        m_hasDateLastModified = true;
2662        try {
2663            if (dateLastModified != null) {
2664                TimestampMode timeMode = TimestampMode.getEnum(CmsMacroResolver.stripMacro(dateLastModified));
2665                switch (timeMode) {
2666                    case FILETIME:
2667                        m_resourceBuilder.setDateLastModified(-1); //Can't get the information right now, must set it afterward.
2668                        break;
2669                    case IMPORTTIME:
2670                        m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
2671                        break;
2672                    case VFSTIME:
2673                    default:
2674                        m_resourceBuilder.setDateLastModified(convertTimestamp(dateLastModified));
2675                        break;
2676                }
2677            } else {
2678                m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
2679            }
2680        } catch (Throwable e) {
2681            setThrowable(e);
2682        }
2683    }
2684
2685    /**
2686     * Sets the dateReleased.<p>
2687     *
2688     * @param dateReleased the dateReleased to set
2689     *
2690     * @see #N_DATERELEASED
2691     * @see #addResourceAttributesRules(Digester, String)
2692     */
2693    public void setDateReleased(String dateReleased) {
2694
2695        try {
2696            if (dateReleased != null) {
2697                m_resourceBuilder.setDateReleased(convertTimestamp(dateReleased));
2698            } else {
2699                m_resourceBuilder.setDateReleased(CmsResource.DATE_RELEASED_DEFAULT);
2700            }
2701        } catch (Throwable e) {
2702            setThrowable(e);
2703        }
2704    }
2705
2706    /**
2707     * Sets the destination.<p>
2708     *
2709     * @param destination the destination to set
2710     *
2711     * @see #N_DESTINATION
2712     * @see #addResourceAttributesRules(Digester, String)
2713     */
2714    public void setDestination(String destination) {
2715
2716        m_destination = destination;
2717    }
2718
2719    /**
2720     * Sets the flags.<p>
2721     *
2722     * @param flags the flags to set
2723     *
2724     * @see #N_FLAGS
2725     * @see #addResourceAttributesRules(Digester, String)
2726     */
2727    public void setFlags(String flags) {
2728
2729        try {
2730            m_resourceBuilder.setFlags(Integer.parseInt(flags));
2731        } catch (Throwable e) {
2732            setThrowable(e);
2733        }
2734    }
2735
2736    /**
2737     * Sets the group Description.<p>
2738     *
2739     * @param groupDescription the description to set
2740     */
2741    public void setGroupDescription(String groupDescription) {
2742
2743        m_groupDescription = groupDescription;
2744    }
2745
2746    /**
2747     * Sets the group Flags.<p>
2748     *
2749     * @param groupFlags the flags to set
2750     */
2751    public void setGroupFlags(String groupFlags) {
2752
2753        try {
2754            m_groupFlags = Integer.parseInt(groupFlags);
2755        } catch (Throwable e) {
2756            setThrowable(e);
2757        }
2758    }
2759
2760    /**
2761     * Sets the group Name.<p>
2762     *
2763     * @param groupName the name to set
2764     */
2765    public void setGroupName(String groupName) {
2766
2767        m_groupName = OpenCms.getImportExportManager().translateGroup(groupName);
2768    }
2769
2770    /**
2771     * Sets the group Parent.<p>
2772     *
2773     * @param groupParent the group Parent to set
2774     */
2775    public void setGroupParent(String groupParent) {
2776
2777        m_groupParent = OpenCms.getImportExportManager().translateGroup(groupParent);
2778    }
2779
2780    /**
2781     * Sets the membership information that could not been set immediately,
2782     * because of import order issues.<p>
2783     */
2784    public void setMembership() {
2785
2786        if ((m_orgUnit == null) || (m_membership == null)) {
2787            return;
2788        }
2789
2790        // get the membership data to set
2791        Map<String, Map<String, String>> membership = m_membership.get(m_orgUnit.getName());
2792        if (membership == null) {
2793            return;
2794        }
2795
2796        // set group membership
2797        Map<String, String> groups = membership.get(I_CmsPrincipal.PRINCIPAL_GROUP);
2798        if (groups != null) {
2799            Iterator<Entry<String, String>> it = groups.entrySet().iterator();
2800            while (it.hasNext()) {
2801                Entry<String, String> entry = it.next();
2802                String userName = entry.getKey();
2803                String groupName = entry.getValue();
2804
2805                // set the users group
2806                try {
2807                    getCms().addUserToGroup(userName, groupName);
2808                } catch (Throwable e) {
2809                    getReport().println(
2810                        Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_GROUP_2, userName, groupName),
2811                        I_CmsReport.FORMAT_WARNING);
2812                    if (LOG.isDebugEnabled()) {
2813                        LOG.debug(e.getLocalizedMessage(), e);
2814                    }
2815                }
2816            }
2817        }
2818
2819        // set role membership
2820        Map<String, String> roles = membership.get(I_CmsPrincipal.PRINCIPAL_USER);
2821        if (roles != null) {
2822            Iterator<Entry<String, String>> it = roles.entrySet().iterator();
2823            while (it.hasNext()) {
2824                Entry<String, String> entry = it.next();
2825                String userName = entry.getKey();
2826                String roleName = entry.getValue();
2827
2828                // set the users roles
2829                CmsRole role = CmsRole.valueOfRoleName(roleName);
2830                try {
2831                    // set the user role
2832                    OpenCms.getRoleManager().addUserToRole(getCms(), role, userName);
2833                    return;
2834                } catch (Throwable e) {
2835                    getReport().println(
2836                        Messages.get().container(Messages.RPT_USER_COULDNT_BE_ADDED_TO_ROLE_2, userName, roleName),
2837                        I_CmsReport.FORMAT_WARNING);
2838                    if (LOG.isDebugEnabled()) {
2839                        LOG.debug(e.getLocalizedMessage(), e);
2840                    }
2841                }
2842            }
2843        }
2844    }
2845
2846    /**
2847     * Sets the organizational unit description.<p>
2848     *
2849     * @param orgUnitDescription the description to set
2850     */
2851    public void setOrgUnitDescription(String orgUnitDescription) {
2852
2853        m_orgUnitDescription = orgUnitDescription;
2854    }
2855
2856    /**
2857     * Sets the organizational unit flags.<p>
2858     *
2859     * @param orgUnitFlags the flags to set
2860     */
2861    public void setOrgUnitFlags(String orgUnitFlags) {
2862
2863        try {
2864            m_orgUnitFlags = Integer.parseInt(orgUnitFlags);
2865        } catch (Throwable e) {
2866            setThrowable(e);
2867        }
2868    }
2869
2870    /**
2871     * Sets the organizational unit name.<p>
2872     *
2873     * @param orgUnitName the name to set
2874     */
2875    public void setOrgUnitName(String orgUnitName) {
2876
2877        m_orgUnitName = orgUnitName;
2878    }
2879
2880    /**
2881     * Sets the project Description.<p>
2882     *
2883     * @param projectDescription the description to set
2884     */
2885    public void setProjectDescription(String projectDescription) {
2886
2887        m_projectDescription = projectDescription;
2888    }
2889
2890    /**
2891     * Sets the project Managers group name.<p>
2892     *
2893     * @param projectManagers the managers group to set
2894     */
2895    public void setProjectManagers(String projectManagers) {
2896
2897        m_projectManagers = projectManagers;
2898    }
2899
2900    /**
2901     * Sets the project Name.<p>
2902     *
2903     * @param projectName the name to set
2904     */
2905    public void setProjectName(String projectName) {
2906
2907        m_projectName = projectName;
2908    }
2909
2910    /**
2911     * Sets the project Users group name.<p>
2912     *
2913     * @param projectUsers the Users group to set
2914     */
2915    public void setProjectUsers(String projectUsers) {
2916
2917        m_projectUsers = projectUsers;
2918    }
2919
2920    /**
2921     * Sets the propertyName.<p>
2922     *
2923     * @param propertyName the propertyName to set
2924     *
2925     * @see #N_NAME
2926     * @see #addResourcePropertyRules(Digester, String)
2927     */
2928    public void setPropertyName(String propertyName) {
2929
2930        m_propertyName = propertyName;
2931    }
2932
2933    /**
2934     * Sets the propertyValue.<p>
2935     *
2936     * @param propertyValue the propertyValue to set
2937     *
2938     * @see #N_VALUE
2939     * @see #addResourcePropertyRules(Digester, String)
2940     */
2941    public void setPropertyValue(String propertyValue) {
2942
2943        m_propertyValue = propertyValue;
2944    }
2945
2946    /**
2947     * Sets the relationId.<p>
2948     *
2949     * @param relationId the relationId to set
2950     *
2951     * @see #N_ID
2952     * @see #addResourceRelationRules(Digester, String)
2953     */
2954    public void setRelationId(String relationId) {
2955
2956        try {
2957            m_relationId = new CmsUUID(relationId);
2958        } catch (Throwable e) {
2959            setThrowable(e);
2960        }
2961    }
2962
2963    /**
2964     * Sets the relationPath.<p>
2965     *
2966     * @param relationPath the relationPath to set
2967     *
2968     * @see #N_PATH
2969     * @see #addResourceRelationRules(Digester, String)
2970     */
2971    public void setRelationPath(String relationPath) {
2972
2973        m_relationPath = relationPath;
2974    }
2975
2976    /**
2977     * Sets the relationType.<p>
2978     *
2979     * @param relationType the relationType to set
2980     *
2981     * @see #N_TYPE
2982     * @see #addResourceRelationRules(Digester, String)
2983     */
2984    public void setRelationType(String relationType) {
2985
2986        try {
2987            m_relationType = CmsRelationType.valueOf(relationType);
2988        } catch (Throwable e) {
2989            setThrowable(e);
2990        }
2991    }
2992
2993    /**
2994     * Sets the resourceId.<p>
2995     *
2996     * @param resourceId the resourceId to set
2997     *
2998     * @see #N_UUIDRESOURCE
2999     * @see #addResourceAttributesRules(Digester, String)
3000     */
3001    public void setResourceId(String resourceId) {
3002
3003        try {
3004            if (!m_resourceBuilder.isFolder()) {
3005                m_resourceBuilder.setResourceId(new CmsUUID(resourceId));
3006            } else {
3007                m_resourceBuilder.setResourceId(new CmsUUID());
3008            }
3009        } catch (Throwable e) {
3010            setThrowable(e);
3011        }
3012    }
3013
3014    /**
3015     * Sets the source.<p>
3016     *
3017     * @param source the source to set
3018     *
3019     * @see #N_SOURCE
3020     * @see #addResourceAttributesRules(Digester, String)
3021     */
3022    public void setSource(String source) {
3023
3024        m_source = source;
3025    }
3026
3027    /**
3028     * Sets the structureId.<p>
3029     *
3030     * @param structureId the structureId to set
3031     *
3032     * @see #N_UUIDSTRUCTURE
3033     * @see #addResourceAttributesRules(Digester, String)
3034     */
3035    public void setStructureId(String structureId) {
3036
3037        try {
3038            m_resourceBuilder.setStructureId(new CmsUUID(structureId));
3039            m_hasStructureId = true;
3040
3041        } catch (Throwable e) {
3042            setThrowable(e);
3043        }
3044
3045    }
3046
3047    /**
3048     * Sets the throwable.<p>
3049     *
3050     * @param throwable the throwable to set
3051     */
3052    public void setThrowable(Throwable throwable) {
3053
3054        m_throwable = throwable;
3055    }
3056
3057    /**
3058     * Sets the type.<p>
3059     *
3060     * @param typeName the type to set
3061     *
3062     * @see #N_TYPE
3063     * @see #addResourceAttributesRules(Digester, String)
3064     */
3065    public void setType(String typeName) {
3066
3067        m_typeName = typeName;
3068        try {
3069            try {
3070                m_resourceBuilder.setType(OpenCms.getResourceManager().getResourceType(typeName));
3071            } catch (@SuppressWarnings("unused") CmsLoaderException e) {
3072                m_unknownType = true;
3073                // TODO: what happens if the resource type is a specialized folder and is not configured??
3074                try {
3075                    m_resourceBuilder.setType(
3076                        OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()));
3077                } catch (@SuppressWarnings("unused") CmsLoaderException e1) {
3078                    // this should really never happen
3079                    m_resourceBuilder.setType(
3080                        OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()));
3081                }
3082            }
3083            if (m_resourceBuilder.getType().isFolder()) {
3084                // ensure folders end with a "/"
3085                if (!CmsResource.isFolder(m_destination)) {
3086                    m_destination += "/";
3087                }
3088            }
3089        } catch (Throwable e) {
3090            setThrowable(e);
3091        }
3092    }
3093
3094    /**
3095     * Sets the user Created.<p>
3096     *
3097     * @param userCreated the user Created to set
3098     */
3099    public void setUserCreated(CmsUUID userCreated) {
3100
3101        m_resourceBuilder.setUserCreated(userCreated);
3102    }
3103
3104    /**
3105     * Sets the userCreated.<p>
3106     *
3107     * @param userCreated the userCreated to set
3108     *
3109     * @see #N_USERCREATED
3110     * @see #addResourceAttributesRules(Digester, String)
3111     */
3112    public void setUserCreated(String userCreated) {
3113
3114        try {
3115            String userCreatedName = OpenCms.getImportExportManager().translateUser(userCreated);
3116            try {
3117                m_resourceBuilder.setUserCreated(getCms().readUser(userCreatedName).getId());
3118            } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
3119                m_resourceBuilder.setUserCreated(getRequestContext().getCurrentUser().getId());
3120            }
3121        } catch (Throwable e) {
3122            setThrowable(e);
3123        }
3124    }
3125
3126    /**
3127     * Sets the user Date Created.<p>
3128     *
3129     * @param userDateCreated the date to set
3130     */
3131    public void setUserDateCreated(String userDateCreated) {
3132
3133        try {
3134            m_userDateCreated = convertTimestamp(userDateCreated);
3135        } catch (Throwable e) {
3136            setThrowable(e);
3137        }
3138    }
3139
3140    /**
3141     * Sets the user email address.<p>
3142     *
3143     * @param userEmail the email address to set
3144     */
3145    public void setUserEmail(String userEmail) {
3146
3147        m_userEmail = userEmail;
3148    }
3149
3150    /**
3151     * Sets the user First name.<p>
3152     *
3153     * @param userFirstname the first name to set
3154     */
3155    public void setUserFirstname(String userFirstname) {
3156
3157        m_userFirstname = userFirstname;
3158    }
3159
3160    /**
3161     * Sets the user Flags.<p>
3162     *
3163     * @param userFlags the flags to set
3164     */
3165    public void setUserFlags(String userFlags) {
3166
3167        try {
3168            m_userFlags = Integer.parseInt(userFlags);
3169        } catch (Throwable e) {
3170            setThrowable(e);
3171        }
3172    }
3173
3174    /**
3175     * Sets the user Last Modified.<p>
3176     *
3177     * @param userLastModified the user Last Modified to set
3178     */
3179    public void setUserLastModified(CmsUUID userLastModified) {
3180
3181        m_resourceBuilder.setUserLastModified(userLastModified);
3182    }
3183
3184    /**
3185     * Sets the userLastModified.<p>
3186     *
3187     * @param userLastModified the userLastModified to set
3188     *
3189     * @see #N_USERLASTMODIFIED
3190     * @see #addResourceAttributesRules(Digester, String)
3191     */
3192    public void setUserLastModified(String userLastModified) {
3193
3194        if (null == userLastModified) { // The optional user last modified information is not provided
3195            m_resourceBuilder.setUserLastModified(getRequestContext().getCurrentUser().getId());
3196        } else { // use the user last modified information from the manifest
3197            try {
3198                String userLastModifiedName = OpenCms.getImportExportManager().translateUser(userLastModified);
3199                try {
3200                    m_resourceBuilder.setUserLastModified(getCms().readUser(userLastModifiedName).getId());
3201                } catch (@SuppressWarnings("unused") CmsDbEntryNotFoundException e) {
3202                    m_resourceBuilder.setUserLastModified(getRequestContext().getCurrentUser().getId());
3203                }
3204            } catch (Throwable e) {
3205                setThrowable(e);
3206            }
3207        }
3208
3209    }
3210
3211    /**
3212     * Sets the user Last name.<p>
3213     *
3214     * @param userLastname the last name to set
3215     */
3216    public void setUserLastname(String userLastname) {
3217
3218        m_userLastname = userLastname;
3219    }
3220
3221    /**
3222     * Sets the user Name.<p>
3223     *
3224     * @param userName the name to set
3225     */
3226    public void setUserName(String userName) {
3227
3228        m_userName = OpenCms.getImportExportManager().translateUser(userName);
3229    }
3230
3231    /**
3232     * Sets the user Password.<p>
3233     *
3234     * @param userPassword the password to set
3235     */
3236    public void setUserPassword(String userPassword) {
3237
3238        m_userPassword = new String(Base64.decodeBase64(userPassword.trim().getBytes()));
3239    }
3240
3241    /**
3242     * Sets the export version from the manifest file.<p>
3243     *
3244     * @param version the export version to set
3245     */
3246    public void setVersion(String version) {
3247
3248        m_version = Integer.parseInt(version);
3249    }
3250
3251    /**
3252     * Adds the XML digester rules for groups.<p>
3253     *
3254     * @param digester the digester to add the rules to
3255     * @param xpath the base xpath for the rules
3256     */
3257    protected void addAccountsGroupRules(Digester digester, String xpath) {
3258
3259        String xp_group = xpath + N_GROUPS + "/" + N_GROUP;
3260        digester.addCallMethod(xp_group, "importGroup");
3261        xp_group += "/";
3262        digester.addCallMethod(xp_group + N_NAME, "setGroupName", 0);
3263        digester.addCallMethod(xp_group + N_DESCRIPTION, "setGroupDescription", 0);
3264        digester.addCallMethod(xp_group + N_FLAGS, "setGroupFlags", 0);
3265        digester.addCallMethod(xp_group + N_PARENTGROUP, "setGroupParent", 0);
3266    }
3267
3268    /**
3269     * Adds the XML digester rules for organizational units.<p>
3270     *
3271     * @param digester the digester to add the rules to
3272     * @param xpath the base xpath for the rules
3273     */
3274    protected void addAccountsOrgunitRules(Digester digester, String xpath) {
3275
3276        digester.addCallMethod(xpath + N_NAME, "setOrgUnitName", 0);
3277        digester.addCallMethod(xpath + N_DESCRIPTION, "setOrgUnitDescription", 0);
3278        digester.addCallMethod(xpath + N_FLAGS, "setOrgUnitFlags", 0);
3279        digester.addCallMethod(xpath + N_RESOURCES + "/" + N_RESOURCE, "addOrgUnitResource", 0);
3280        digester.addCallMethod(xpath + N_RESOURCES, "importOrgUnit");
3281    }
3282
3283    /**
3284     * Adds the XML digester rules for users.<p>
3285     *
3286     * @param digester the digester to add the rules to
3287     * @param xpath the base xpath for the rules
3288     */
3289    protected void addAccountsUserRules(Digester digester, String xpath) {
3290
3291        String xp_user = xpath + N_USERS + "/" + N_USER + "/";
3292        digester.addCallMethod(xp_user + N_NAME, "setUserName", 0);
3293        digester.addCallMethod(xp_user + N_PASSWORD, "setUserPassword", 0);
3294        digester.addCallMethod(xp_user + N_FIRSTNAME, "setUserFirstname", 0);
3295        digester.addCallMethod(xp_user + N_LASTNAME, "setUserLastname", 0);
3296        digester.addCallMethod(xp_user + N_EMAIL, "setUserEmail", 0);
3297        digester.addCallMethod(xp_user + N_FLAGS, "setUserFlags", 0);
3298        digester.addCallMethod(xp_user + N_DATECREATED, "setUserDateCreated", 0);
3299        digester.addCallMethod(xp_user + N_USERINFO, "importUser");
3300
3301        String xp_info = xp_user + N_USERINFO + "/" + N_USERINFO_ENTRY;
3302        digester.addCallMethod(xp_info, "importUserInfo", 3);
3303        digester.addCallParam(xp_info, 0, A_NAME);
3304        digester.addCallParam(xp_info, 1, A_TYPE);
3305        digester.addCallParam(xp_info, 2);
3306
3307        digester.addCallMethod(xp_user + N_USERROLES + "/" + N_USERROLE, "importUserRole", 0);
3308        digester.addCallMethod(xp_user + N_USERGROUPS + "/" + N_USERGROUP, "importUserGroup", 0);
3309    }
3310
3311    /**
3312     * Adds the XML digester rules for projects.<p>
3313     *
3314     * @param digester the digester to add the rules to
3315     * @param xpath the base xpath for the rules
3316     */
3317    protected void addProjectRules(Digester digester, String xpath) {
3318
3319        digester.addCallMethod(xpath + N_NAME, "setProjectName", 0);
3320        digester.addCallMethod(xpath + N_DESCRIPTION, "setProjectDescription", 0);
3321        digester.addCallMethod(xpath + N_MANAGERSGROUP, "setProjectManagers", 0);
3322        digester.addCallMethod(xpath + N_USERSGROUP, "setProjectUsers", 0);
3323        digester.addCallMethod(xpath + N_RESOURCES + "/" + N_RESOURCE, "addProjectResource", 0);
3324        digester.addCallMethod(xpath + N_RESOURCES, "importProject");
3325    }
3326
3327    /**
3328     * Adds the XML digester rules for resource access control entries.<p>
3329     *
3330     * @param digester the digester to add the rules to
3331     * @param xpath the base xpath for the rules
3332     */
3333    protected void addResourceAceRules(Digester digester, String xpath) {
3334
3335        String xp_ace = xpath + N_ACCESSCONTROL_ENTRIES + "/" + N_ACCESSCONTROL_ENTRY;
3336        digester.addCallMethod(xp_ace, "addAccessControlEntry");
3337        digester.addCallMethod(xp_ace + "/" + N_ACCESSCONTROL_PRINCIPAL, "setAcePrincipalId", 0);
3338        digester.addCallMethod(xp_ace + "/" + N_FLAGS, "setAceFlags", 0);
3339        String xp_perms = xp_ace + "/" + N_ACCESSCONTROL_PERMISSIONSET + "/";
3340        digester.addCallMethod(xp_perms + N_ACCESSCONTROL_ALLOWEDPERMISSIONS, "setAcePermissionsAllowed", 0);
3341        digester.addCallMethod(xp_perms + N_ACCESSCONTROL_DENIEDPERMISSIONS, "setAcePermissionsDenied", 0);
3342    }
3343
3344    /**
3345     * Adds the XML digester rules for resource attributes.<p>
3346     *
3347     * @param digester the digester to add the rules to
3348     * @param xpath the base xpath for the rules
3349     */
3350    protected void addResourceAttributesRules(Digester digester, String xpath) {
3351
3352        digester.addCallMethod(xpath + N_SOURCE, "setSource", 0);
3353        digester.addCallMethod(xpath + N_DESTINATION, "setDestination", 0);
3354        digester.addCallMethod(xpath + N_TYPE, "setType", 0);
3355        digester.addCallMethod(xpath + N_UUIDSTRUCTURE, "setStructureId", 0);
3356        digester.addCallMethod(xpath + N_UUIDRESOURCE, "setResourceId", 0);
3357        digester.addCallMethod(xpath + N_DATELASTMODIFIED, "setDateLastModified", 0);
3358        digester.addCallMethod(xpath + N_USERLASTMODIFIED, "setUserLastModified", 0);
3359        digester.addCallMethod(xpath + N_DATECREATED, "setDateCreated", 0);
3360        digester.addCallMethod(xpath + N_USERCREATED, "setUserCreated", 0);
3361        digester.addCallMethod(xpath + N_DATERELEASED, "setDateReleased", 0);
3362        digester.addCallMethod(xpath + N_DATEEXPIRED, "setDateExpired", 0);
3363        digester.addCallMethod(xpath + N_FLAGS, "setFlags", 0);
3364    }
3365
3366    /**
3367     * Adds the XML digester rules for resource properties.<p>
3368     *
3369     * @param digester the digester to add the rules to
3370     * @param xpath the base xpath for the rules
3371     */
3372    protected void addResourcePropertyRules(Digester digester, String xpath) {
3373
3374        String xp_props = xpath + N_PROPERTIES + "/" + N_PROPERTY;
3375        // first rule in case the type is implicit
3376        digester.addCallMethod(xp_props, "addProperty");
3377        // second rule in case the type is given
3378        digester.addCallMethod(xp_props, "addProperty", 1);
3379        digester.addCallParam(xp_props, 0, A_TYPE);
3380
3381        digester.addCallMethod(xp_props + "/" + N_NAME, "setPropertyName", 0);
3382        digester.addCallMethod(xp_props + "/" + N_VALUE, "setPropertyValue", 0);
3383
3384    }
3385
3386    /**
3387     * Adds the XML digester rules for resource relations.<p>
3388     *
3389     * @param digester the digester to add the rules to
3390     * @param xpath the base xpath for the rules
3391     */
3392    protected void addResourceRelationRules(Digester digester, String xpath) {
3393
3394        String xp_rels = xpath + N_RELATIONS + "/" + N_RELATION;
3395        digester.addCallMethod(xp_rels, "addRelation");
3396        digester.addCallMethod(xp_rels + "/" + N_ID, "setRelationId", 0);
3397        digester.addCallMethod(xp_rels + "/" + N_PATH, "setRelationPath", 0);
3398        digester.addCallMethod(xp_rels + "/" + N_TYPE, "setRelationType", 0);
3399    }
3400
3401    /**
3402     * Checks if the resources is in the list of immutable resources.<p>
3403     *
3404     * @param resourceName the name of the resource
3405     *
3406     * @return <code>true</code> or <code>false</code>
3407     */
3408    protected boolean checkImmutable(String resourceName) {
3409
3410        boolean resourceImmutable = false;
3411        if (getImmutableResources().contains(resourceName)) {
3412            if (LOG.isDebugEnabled()) {
3413                LOG.debug(
3414                    Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_RESOURCENAME_IMMUTABLE_1, resourceName));
3415            }
3416            // this resource must not be modified by an import if it already exists
3417            String storedSiteRoot = getRequestContext().getSiteRoot();
3418            try {
3419                getRequestContext().setSiteRoot("/");
3420                getCms().readResource(resourceName);
3421                resourceImmutable = true;
3422                if (LOG.isDebugEnabled()) {
3423                    LOG.debug(
3424                        Messages.get().getBundle().key(Messages.LOG_IMPORTEXPORT_IMMUTABLE_FLAG_SET_1, resourceName));
3425                }
3426            } catch (CmsException e) {
3427                // resourceNotImmutable will be true
3428                if (LOG.isDebugEnabled()) {
3429                    LOG.debug(
3430                        Messages.get().getBundle().key(
3431                            Messages.LOG_IMPORTEXPORT_ERROR_ON_TEST_IMMUTABLE_1,
3432                            resourceName),
3433                        e);
3434                }
3435            } finally {
3436                getRequestContext().setSiteRoot(storedSiteRoot);
3437            }
3438        }
3439        return resourceImmutable;
3440    }
3441
3442    /**
3443     * Converts a given digest to base64 encoding.<p>
3444     *
3445     * @param value the digest value in the legacy encoding
3446     *
3447     * @return the digest in the new encoding
3448     */
3449    protected String convertDigestEncoding(String value) {
3450
3451        byte[] data = new byte[value.length() / 2];
3452
3453        for (int i = 0; i < data.length; i++) {
3454            data[i] = (byte)(Integer.parseInt(value.substring(i * 2, (i * 2) + 2), 16) - 128);
3455        }
3456        return new String(Base64.encodeBase64(data));
3457    }
3458
3459    /**
3460     * Convert a given time stamp from a String format to a long value.<p>
3461     *
3462     * The time stamp is either the string representation of a long value (old export format)
3463     * or a user-readable string format.<p>
3464     *
3465     * @param timestamp time stamp to convert
3466     *
3467     * @return long value of the time stamp
3468     */
3469    protected long convertTimestamp(String timestamp) {
3470
3471        long value = 0;
3472        // try to parse the time stamp string
3473        // if it successes, its an old style long value
3474        try {
3475            value = Long.parseLong(timestamp);
3476        } catch (@SuppressWarnings("unused") NumberFormatException e) {
3477            // the time stamp was in in a user-readable string format, create the long value form it
3478            try {
3479                value = CmsDateUtil.parseHeaderDate(timestamp);
3480            } catch (@SuppressWarnings("unused") ParseException pe) {
3481                value = System.currentTimeMillis();
3482            }
3483        }
3484        return value;
3485    }
3486
3487    /**
3488     * Create a CmsResource object from the currently set field values.<p>
3489     *
3490     * @param translatedName the resource name
3491     * @param size the size
3492     * @return the new CmsResource object
3493     */
3494    protected CmsResource createResourceObjectFromFields(String translatedName, int size) {
3495
3496        m_resourceBuilder.setRootPath(translatedName);
3497        m_resourceBuilder.setState(CmsResource.STATE_NEW);
3498        m_resourceBuilder.setProjectLastModified(getRequestContext().getCurrentProject().getUuid());
3499        m_resourceBuilder.setLength(size);
3500        m_resourceBuilder.setSiblingCount(1);
3501        m_resourceBuilder.setVersion(0);
3502        m_resourceBuilder.setDateContent(System.currentTimeMillis());
3503        return m_resourceBuilder.buildResource();
3504    }
3505
3506    /**
3507     * This method goes through the manifest, records all files from the manifest for which the content also
3508     * exists in the zip file, and stores their resource ids in m_contentFiles.<p>
3509     *
3510     * @throws CmsImportExportException thrown when the manifest.xml can't be opened as stream.
3511     * @throws IOException thrown if the manifest.xml stream causes problems during parsing and/or closing.
3512     * @throws SAXException thrown if parsing the manifest.xml fails
3513     */
3514    protected void findContentFiles() throws CmsImportExportException, IOException, SAXException {
3515
3516        Digester digester = new Digester();
3517        digester.setUseContextClassLoader(true);
3518        digester.setValidating(false);
3519        digester.setEntityResolver(new CmsXmlEntityResolver(null));
3520        digester.setRuleNamespaceURI(null);
3521        digester.setErrorHandler(new CmsXmlErrorHandler(CmsImportExportManager.EXPORT_MANIFEST));
3522
3523        digester.addCallMethod("export/files/file", "addContentFile", 2);
3524        digester.addCallParam("export/files/file/source", 0);
3525        digester.addCallParam("export/files/file/uuidresource", 1);
3526        m_contentFiles.clear();
3527        digester.push(this);
3528        InputStream stream = null;
3529        try {
3530            stream = m_helper.getFileStream(CmsImportExportManager.EXPORT_MANIFEST);
3531            digester.parse(stream);
3532        } finally {
3533            if (stream != null) {
3534                stream.close();
3535            }
3536        }
3537    }
3538
3539    /**
3540     * Gets the import helper instance.<p>
3541     *
3542     * @return the import helper
3543     */
3544    protected CmsImportHelper getHelper() {
3545
3546        return m_helper;
3547    }
3548
3549    /**
3550     * Returns the list of properties to ignore during import.<p>
3551     *
3552     * @return the list of properties to ignore during import
3553     */
3554    protected List<String> getIgnoredProperties() {
3555
3556        if (m_ignoredProperties == null) {
3557            // get list of ignored properties
3558            m_ignoredProperties = OpenCms.getImportExportManager().getIgnoredProperties();
3559            if (m_ignoredProperties == null) {
3560                m_ignoredProperties = Collections.emptyList();
3561            }
3562        }
3563        return m_ignoredProperties;
3564    }
3565
3566    /**
3567     * Returns the list of immutable resources.<p>
3568     *
3569     * @return the list of immutable resources
3570     */
3571    protected List<String> getImmutableResources() {
3572
3573        if (m_immutables == null) {
3574            // get list of immutable resources
3575            m_immutables = OpenCms.getImportExportManager().getImmutableResources();
3576            if (m_immutables == null) {
3577                m_immutables = Collections.emptyList();
3578            }
3579            if (LOG.isDebugEnabled()) {
3580                LOG.debug(
3581                    Messages.get().getBundle().key(
3582                        Messages.LOG_IMPORTEXPORT_IMMUTABLE_RESOURCES_SIZE_1,
3583                        Integer.toString(m_immutables.size())));
3584            }
3585        }
3586        return m_immutables;
3587    }
3588
3589    /**
3590     * Fills the unset fields for an imported resource with default values.<p>
3591     *
3592     * @throws CmsImportExportException if something goes wrong
3593     */
3594    protected void setDefaultsForEmptyResourceFields() throws CmsImportExportException {
3595
3596        // get UUID for the structure
3597        if (m_resourceBuilder.getStructureId() == null) {
3598            // if null generate a new structure id
3599            m_resourceBuilder.setStructureId(new CmsUUID());
3600        }
3601
3602        if ((m_resourceBuilder.getResourceId() == null) && m_unknownType) {
3603            try {
3604                m_resourceBuilder.setType(OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName()));
3605            } catch (CmsLoaderException e) {
3606                LOG.error(e.getLocalizedMessage(), e);
3607            }
3608        }
3609        if (m_resourceBuilder.getType().isFolder()) {
3610            // ensure folders end with a "/"
3611            if (!CmsResource.isFolder(m_destination)) {
3612                m_destination += "/";
3613            }
3614        }
3615
3616        // get UUIDs for the resource
3617        if ((m_resourceBuilder.getResourceId() == null) || (m_resourceBuilder.getType().isFolder())) {
3618            // folders get always a new resource UUID
3619            m_resourceBuilder.setResourceId(new CmsUUID());
3620            m_resourceIdWasNull = true;
3621        }
3622
3623        // read date last modified from the resource, default to currentTime for folders
3624        if (m_resourceBuilder.getDateLastModified() == DATE_LAST_MODIFICATION_FILETIME) {
3625            if (null != m_source) {
3626                m_resourceBuilder.setDateLastModified(m_helper.getFileModification(m_source));
3627            } else {
3628                m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
3629            }
3630        }
3631
3632        if (m_resourceBuilder.getDateLastModified() == DATE_LAST_MODIFICATION_UNSPECIFIED) {
3633            m_resourceBuilder.setDateLastModified(System.currentTimeMillis());
3634        }
3635
3636        if (null == m_resourceBuilder.getUserLastModified()) {
3637            m_resourceBuilder.setUserLastModified(m_cms.getRequestContext().getCurrentUser().getId());
3638        }
3639
3640        if (m_resourceBuilder.getDateCreated() == DATE_CREATED_UNSPECIFIED) {
3641            m_resourceBuilder.setDateCreated(System.currentTimeMillis());
3642        }
3643
3644        if (m_resourceBuilder.getUserCreated().isNullUUID()) {
3645            m_resourceBuilder.setUserCreated(getRequestContext().getCurrentUser().getId());
3646        }
3647
3648        if (m_properties == null) {
3649            m_properties = new HashMap<String, CmsProperty>();
3650        }
3651    }
3652
3653    /**
3654     * Checks whether the content for the resource being imported exists either in the VFS or in the import file.<p>
3655     *
3656     * @param resource the resource which should be checked
3657     *
3658     * @return true if the content exists in the VFS or import file
3659     */
3660    private boolean hasContentInVfsOrImport(CmsResource resource) {
3661
3662        if (m_contentFiles.contains(resource.getResourceId())) {
3663            return true;
3664        }
3665        try {
3666            List<CmsResource> resources = getCms().readSiblings(resource, CmsResourceFilter.ALL);
3667            if (!resources.isEmpty()) {
3668                return true;
3669            }
3670        } catch (CmsException e) {
3671            LOG.warn(e.getLocalizedMessage(), e);
3672        }
3673        return false;
3674
3675    }
3676}