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