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