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