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