/*
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ImportMaintenanceAction.java,v $
 * Revision 1.25  2008/02/12 09:33:48  korowa
 * Eine Möglichkeit für den Benutzer hinzugefügt die Emailsart auszuwählen(HTML oder Plaintext)
 *
 * Revision 1.24  2007/11/13 11:50:10  korowa
 * CreatorId für Gruppen und Benutzer werden jetzt soweit möglich an export System angepasst(nur für neu angelegte ObjeKte), damit dedizierte Admins ihre Benutzer und Gruppen behalten. Dedizierte Rechte werden übertragen.
 *
 * Revision 1.23  2007/11/05 15:11:54  korowa
 * bugfixing
 *
 * Revision 1.22  2007/11/05 11:57:55  marbobo
 * *** empty log message ***
 *
 * Revision 1.21  2007/11/05 11:34:11  korowa
 * Benachrichtigungen mit neuen Passwörtern werden direkt nach dem Einfügen in den Datenbank abgeschickt
 * Der Name von übergebenen dynamischen Attributen bei gemappten Benutzern werden mit "_migration" verfollständigt
 *
 * Revision 1.18  2007/11/02 20:34:11  marbobo
 * + Bugfix (Statt List werden HashSet benutzt)
 *
 * Revision 1.17  2007/11/02 19:52:23  marbobo
 * + Bugfix (Statt List werden HashSet benutzt)
 *
 * Revision 1.16  2007/10/30 15:48:04  korowa
 * Beim Archivieren und Exportieren werden bei Documentennamen die Ids miteingegeben
 *
 * Revision 1.15  2007/10/30 14:43:34  marbobo
 * + removed unnecessary statements
 *
 * Revision 1.14  2007/10/29 09:19:50  marbobo
 * *** empty log message ***
 *
 * Revision 1.13  2007/10/25 15:01:32  korowa
 * HomeCategory wird jetzt gesetzt,License aktualisiert,Passwörter für geänderte Benutzer werden generiert
 *
 * Revision 1.12  2007/10/23 07:58:10  korowa
 * MigrationLog hinzugefügt,alle Objekte werden da rausgeschrieben, bugfixing: LastChangerId von User wird jetzt aktualisiert,
 *
 * Revision 1.11  2007/10/18 14:22:03  korowa
 * bugfixing
 *
 * Revision 1.10  2007/10/18 14:02:54  korowa
 * bugfixing
 *
 * Revision 1.9  2007/10/18 09:55:54  korowa
 * Passwörter werden nur verschlüsselt exportiert, und werden bei importierten Benutzer nicht neu generiert. CreatorId für aclEntries werden gesetzt.
 *
 * Revision 1.8  2007/10/12 12:38:56  korowa
 * bugfixing
 *
 * Revision 1.7  2007/10/09 13:06:17  korowa
 * Hilfestellung für Importfunktion als Popup hinzugefügt
 *
 * Revision 1.6  2007/09/19 07:56:07  korowa
 * strengere Regel für ImportDatei
 *
 * Revision 1.5  2007/09/18 14:29:43  korowa
 * bugfixing
 *
 * Revision 1.4  2007/09/18 07:48:29  korowa
 * Anpassung an die Änderung des ArchievCategorie, die Ordnernamen werden jetzt als Id abgelegt und ausgelesen
 *
 * Revision 1.3  2007/09/17 09:29:17  korowa
 * bugfixing
 *
 * Revision 1.2  2007/09/05 09:42:43  korowa
 * Bei Importieren von Dokumenten werden jetzt Benachrichtigungen verschickt
 *
 * Revision 1.1  2007/08/28 12:15:57  korowa
 * Export- und Importfunktionen hinzugefügt
 * 
 *
 */
package vkc.administration.action;

import java.io.*;

import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import com.thoughtworks.xstream.XStream;

import vkc.administration.form.ImportMaintenanceForm;

import vkc.db.common.ConversionStatus;
import vkc.db.entities.VKCAclEntry;
import vkc.db.entities.VKCAclType;
import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;

import vkc.db.entities.VKCDynUserAttribute;
import vkc.db.entities.VKCDynaAttribute;
import vkc.db.entities.VKCGroup;
import vkc.db.entities.VKCMigrationObjects;
import vkc.db.entities.VKCSearchQuery;
import vkc.db.entities.VKCSubCategory;
import vkc.db.entities.VKCUser;
import vkc.db.helper.DBHelper;
import vkc.db.serializer.VKCCategorySerializer;

import vkc.db.serializer.VKCDocumentSerializer;
import vkc.db.serializer.VKCGroupSerializer;
import vkc.db.serializer.VKCSysParameterSerializer;
import vkc.db.serializer.VKCUserRegSearchQuerySerializer;
import vkc.db.serializer.VKCUserSerializer;
import vkc.exception.DBException;

import java.util.Date;

import vkc.messenger.mail.UserDocMailsPopulator;
import vkc.misc.ArchiveCategory;
import vkc.misc.MailUtils;
import vkc.misc.TemplateParser;
import vkc.misc.VKCLogManager;
import vkc.security.VKCAcl;
import vkc.util.FileUtils;
import vkc.util.ServletUtils;
import vkc.util.StringUtils;
import vkc.util.VKCCoder;

import vkc.util.VKCStringUtils;

import vkc.util.treeview.TreeViewManager;
import vkc.view.WebShare;
import vkc.view.bean.ResourceInfo;

public final class ImportMaintenanceAction extends SystemMaintenanceAction {
    private ActionForward INFO_FORWARD = new ActionForward("/templates/${template.name}/common/InfoPage.jsp");

    public ActionForward execute(ActionMapping mapping, ActionForm f, HttpServletRequest request, HttpServletResponse response) throws ServletException {
        ImportMaintenanceForm form = (ImportMaintenanceForm) f;

        VKCUser user = form.getUser();

        if (!user.hasAdminPrivileges() && !user.getManageOwnUsers()) {
            request.setAttribute(WebShare.INFO_KEY, "vkc.info.access_denied");

            return INFO_FORWARD;
        }

        if (request.getParameter("action.import") != null) {
            try {
                handleImportAction(form, request);
            } catch (DBException e) {
                VKCLogManager.errorLog(this, "3", "The import failed!", e);
                e.printStackTrace();
            }

        }

        return this.handleInitializeAction(form, request);
    }

    private void handleImportAction(ImportMaintenanceForm form, HttpServletRequest request) throws ServletException, DBException {
        VKCCategory root = null;
        String rootName = "";
        Connection conn = null;
        Set notSendedForUser = new HashSet();
        VKCLogManager.migrationLog(form.getUser().getFullName(), " Started import!");

        if (form.getStep() == form.STEP_PREPARE) {
            ActionErrors errors = form.unzip();
            
            // falls fehlerfrei entzippt
            if (errors.isEmpty()) {
                // falls Namenskonflikte durch VKC gelöst werden sollen, sofort
                // zum
                // Import gehen
                if (form.isSelfNameGen()) {
                    form.setStep(form.STEP_IMPORT);
                } else {
                    // Namen von allen Usern auf Konflikte überprüfen und
                    // abspeichern falls vorhanden
                    form.setUserConflictNames(new ArrayList());
                    Iterator iterUser = form.getImportUser().iterator();
                    LabelValueBean conflictName = null;
                    
                    while (iterUser.hasNext()) {
                        VKCUser user = (VKCUser) iterUser.next();
                        
                        if (VKCUserSerializer.isUserExistent(user.getUser())) {
                            conflictName = new LabelValueBean(user.getUser(), user.getUser());
                            form.getUserConflictNames().add(conflictName);
                        }
                    }
                    // Namen von allen Gruppen auf Konflikte überprüfen und
                    // abspeichern falls vorhanden
                    form.setGroupConflictNames(new ArrayList());
                    Iterator itergroup = form.getImportGroups().iterator();
                    
                    while (itergroup.hasNext()) {
                        VKCGroup group = (VKCGroup) itergroup.next();
                        
                        if (VKCGroupSerializer.isGroupExistent(group.getName())) {
                            conflictName = new LabelValueBean(group.getName(), group.getName());
                            form.getGroupConflictNames().add(conflictName);
                        }
                    }
                    // falls keine Konflikte dann Importieren
                    if (form.getGroupConflictNames().isEmpty() && form.getUserConflictNames().isEmpty()) {
                        form.setStep(form.STEP_IMPORT);
                    } else {
                        form.setStep(form.STEP_SHOWCONFLICTS);
                    }
                }
            } else
                saveErrors(request, errors);
        } else if (form.getStep() == form.STEP_SHOWCONFLICTS) {
            File objects = new File(form.getPathForObjects());
            FileInputStream fis;
            // ObjectInputStream o;

            try {
                fis = new FileInputStream(objects);
                XStream xstream = new XStream();
                VKCMigrationObjects migrationObjects = ((VKCMigrationObjects) xstream.fromXML(fis));
                form.setImportCategories(migrationObjects.getMigrationCategories());
                form.setImportDocuments(migrationObjects.getMigrationDocuments());
                form.setImportGroups(migrationObjects.getMigrationGroups());
                form.setImportUser(migrationObjects.getMigrationUsers());
                form.setImportQueries(migrationObjects.getMigrationCategoryQueries());
                form.setImportUserQueries(migrationObjects.getMigrationUserQueries());
                fis.close();
            } catch (FileNotFoundException e) {
                VKCLogManager.errorLog(this, "1", "Can't find the importfile!", e);
                VKCLogManager.migrationLog(this, "Can't find the importfile!");
            } catch (IOException e) {
                VKCLogManager.errorLog(this, "2", "Exception by read importfile!", e);
                VKCLogManager.migrationLog(e, "Exception by read importfile!");
            }

            form.setStep(form.STEP_IMPORT);
        }
        
        if (form.getStep() == form.STEP_IMPORT) {
            try {
                readObjects(form);
                conn = WebShare.database.getConnection();
                // Gruppen bearbeiten und speichern
                Iterator iterGroups = form.getImportGroups().iterator();
                
                while (iterGroups.hasNext()) {
                    VKCGroup group = (VKCGroup) iterGroups.next();
                    // wenn die Namen automatische generiert sollen
                    // falls die Gruppe nicht existiert oder
                    // falls der neuer Name der Gruppe nicht existiert
                    if (form.isSelfNameGen() || !VKCGroupSerializer.isGroupExistent(group.getName()) || !VKCGroupSerializer.isGroupExistent((String) form.getConflictGroupNames().get(group.getName()))) {
                        group.setAdminPrivileges(Boolean.FALSE);
                        group.setLastChangerId(form.getUser().getUserId());
                        
                        if (VKCGroupSerializer.isGroupExistent(group.getName())) {
                            group.setName(form.getNewGroupName(group.getName()));
                            form.addImportName(form.getImportGroupName(), group.getName());
                        }
                        
                        Integer alteGroupId = group.getGroupId();
                        group.setGroupId(DBHelper.getNewId(conn, "Groups", "groupId"));
                        form.getGroupIds().put(alteGroupId, group.getGroupId());
                    } else {
                        VKCGroup alterGroup = VKCGroupSerializer.retrieveGroup(form.getConflictGroupNames().get(group.getName()));
                        form.getGroupIds().put(group.getGroupId(), alterGroup.getGroupId());
                    }
                }

                // Veraltete Informationen von Usern rausfiltern und dann den
                // Benutzer speichern
                Set changedUsers = new HashSet();
                Iterator iterUser = form.getImportUser().iterator();                
                while (iterUser.hasNext()) {
                    VKCUser user = (VKCUser) iterUser.next();
                    // wenn die Namen automatische generiert sollen
                    // wenn der Benutzer mit gleichen Namen noch nicht existiert
                    // oder falls doch
                    // aber der neueName wird geändert
                    if (form.isSelfNameGen() || !VKCUserSerializer.isUserExistent(user.getUser()) || !VKCUserSerializer.isUserExistent((String) form.getConflictUserNames().get(user.getUser()))) {
                        Integer alteUserId = user.getUserId();
                        user.setUserId(DBHelper.getNewId(conn, "Users", "userId"));
                        user.getLicense().clear();
                        form.getUserIds().put(alteUserId, user.getUserId());
                        VKCDynUserAttribute alteId = new VKCDynUserAttribute();
                        alteId.setName("UserId before migration");
                        alteId.setValue(alteUserId.toString());
                        alteId.setUserId(user.getUserId());
                        alteId.setAutorization(new Integer(VKCDynUserAttribute.AUTORIZATION_READ));
                        user.addDynaAttribute(alteId);
                        
                        if (VKCUserSerializer.isUserExistent(user.getUser())) {
                            VKCDynUserAttribute alterUserName = new VKCDynUserAttribute();
                            alterUserName.setName("Username before migration");
                            alterUserName.setValue(user.getUser());
                            alterUserName.setUserId(user.getUserId());
                            alterUserName.setAutorization(new Integer(VKCDynUserAttribute.AUTORIZATION_READ));
                            user.addDynaAttribute(alterUserName);
                            user.setUser(form.getNewUserName(user.getUser()));
                            form.addImportName(form.getImportUserName(), user.getUser());
                            // Der Passwort wird hier neu generiert,da er von
                            // der Namen des Users abhängt
                            String password = RandomStringUtils.randomAlphanumeric(8);
                            byte[] md5Bytes = (user.getUser() + password).getBytes("ISO-8859-1");

                            MessageDigest digest;
                            digest = MessageDigest.getInstance("MD5");
                            digest.reset();
                            digest.update(md5Bytes);
                            byte[] fingerPrint = digest.digest();
                            fingerPrint = VKCCoder.base64Encode(fingerPrint);
                            String md5Password = new String(fingerPrint, "ISO-8859-1");
                            user.setPasswordChanged(false);
                            user.setPassword(md5Password);
                            user.setClearPassword(password);
                            user.setPasswordChangedTs(new Timestamp(System.currentTimeMillis()));
                            notSendedForUser.add(user);
                           

                        }                       
                        user.setAdminPrivileges(false);
                        user.setRegisteredCategories(null);
                        user.setRegisteredDocuments(null);
                        user.setRegisteredQueries(null);
                        // GroupIds aktualisieren
                        Set newUserGroups = new HashSet();
                        Iterator iterUserGroups = user.getGroups().iterator();
                        
                        while (iterUserGroups.hasNext()) {
                            VKCGroup group = (VKCGroup) iterUserGroups.next();
                            if (form.getGroupIds().containsKey(group.getGroupId())) {
                                Integer groupNewId = (Integer) form.getGroupIds().get(group.getGroupId());
                                VKCGroup newGroup = VKCGroupSerializer.retrieveGroup(groupNewId);
                                
                                if (newGroup != null) {
                                    newUserGroups.add(newGroup);
                                } else {
                                    group.setGroupId(groupNewId);
                                    newUserGroups.add(group);
                                }
                            }
                        }
                        
                        if (newUserGroups.isEmpty())
                            newUserGroups = null;
                        user.setGroups(newUserGroups);
                        Iterator iterDynUserAttr = user.getDynaAttributes().iterator();
                        
                        while (iterDynUserAttr.hasNext()) {
                            VKCDynUserAttribute attr = (VKCDynUserAttribute) iterDynUserAttr.next();
                            attr.setUserId(user.getUserId());
                        }
                    } else {// falls der migrierte Benutzer = existierende
                        // Benutzer
                        VKCUser alterUser = VKCUserSerializer.retrieveUser(form.getConflictUserNames().get(user.getUser()));
                        form.getUserIds().put(user.getUserId(), alterUser.getUserId());
                        Iterator iterDynUserAttr = user.getDynaAttributes().iterator();
                        
                        while (iterDynUserAttr.hasNext()) {
                            VKCDynUserAttribute attr = (VKCDynUserAttribute) iterDynUserAttr.next();
                            attr.setUserId(alterUser.getUserId());
                            attr.setName(attr.getName()+"_migration");
                            alterUser.addDynaAttribute(attr);
                        }
                        //dedizierte Adminrechte setzen
                        if(user.getManageOwnGroups()){
                            alterUser.setManageOwnGroups(true);
                        }
                        if(user.getManageOwnUsers()){
                            alterUser.setManageOwnUsers(true);
                            if(user.isManageOwnUsersSystemViews()){
                                alterUser.setManageOwnUsersSystemViews(true);
                            }
                        }
                        if(user.isManageVirtualDocumentQueries()){
                            alterUser.setManageVirtualDocumentQueries(true);
                        }
                        if(user.getManageOwnProxies()){
                            alterUser.setManageOwnProxies(true);
                        }
                        user.setLastChanged(new Timestamp(System.currentTimeMillis()));
                        user.setLastChangerId(form.getUser().getUserId());

                        Set newUserGroups = new HashSet();
                        Iterator iterUserGroups = user.getGroups().iterator();
                        
                        while (iterUserGroups.hasNext()) {
                            VKCGroup group = (VKCGroup) iterUserGroups.next();
                            
                            if (form.getGroupIds().containsKey(group.getGroupId())) {
                                Integer groupNewId = (Integer) form.getGroupIds().get(group.getGroupId());
                                VKCGroup userGroup = VKCGroupSerializer.retrieveGroup(groupNewId);
                                // falls die Gruppe schon existiert und nicht in
                                // Benutzersgruppen vorhanden ist
                                if (userGroup != null && !alterUser.getGroups().contains(userGroup)) {
                                    newUserGroups.add(userGroup);
                                } else {// sonst ist es eine Importierte Gruppe
                                    group.setGroupId(groupNewId);
                                    newUserGroups.add(group);
                                }
                            }
                        }
                        
                        alterUser.getGroups().addAll(newUserGroups);
                        changedUsers.add(alterUser);
                        iterUser.remove();
                    }
                }
                
                form.getImportUser().addAll(changedUsers);
                
                
                
                // User Ids für Gruppen aktualisieren
                iterGroups = form.getImportGroups().iterator();
                Set userIds = new HashSet();
                Set changedGroups = new HashSet();
                
                while (iterGroups.hasNext()) {
                    VKCGroup group = (VKCGroup) iterGroups.next();
                    Iterator iterUserIds = group.getGroupUserIds().iterator();
                    
                    while (iterUserIds.hasNext()) {
                        Object userId = iterUserIds.next();
                        
                        if (form.getUserIds().containsKey(userId)) {
                            userIds.add(form.getUserIds().get(userId));
                        }
                    }
                    if(!VKCGroupSerializer.isGroupExistent(group.getName())){
                        if (form.getUserIds().containsKey(group.getCreatorId())) {
                            group.setCreatorId((Integer) form.getUserIds().get(group.getCreatorId()));
                        } else {
                            group.setCreatorId(form.getUser().getUserId());
                            group.setCreated(new Timestamp(System.currentTimeMillis()));
                        }
                    }
                    if (form.getUserIds().containsKey(group.getLastChangerId())) {
                        group.setLastChangerId((Integer) form.getUserIds().get(group.getLastChangerId()));
                    } else {
                        group.setLastChangerId(form.getUser().getUserId());
                        group.setLastChanged(new Timestamp(System.currentTimeMillis()));
                    }
                    
                    // falls die importierte Gruppe = vorhandene Gruppe
                    if (VKCGroupSerializer.isGroupExistent(group.getName()) && form.getConflictGroupNames().containsKey(group.getName())) {
                        if (VKCGroupSerializer.isGroupExistent((String) form.getConflictGroupNames().get(group.getName()))) {
                            VKCGroup alterGroup = VKCGroupSerializer.retrieveGroup(form.getConflictGroupNames().get(group.getName()));
                            alterGroup.getGroupUserIds().addAll(group.getGroupUserIds());
                            changedGroups.add(alterGroup);
                            iterGroups.remove();
                        } else {
                            group.setName((String) form.getConflictGroupNames().get(group.getName()));
                        }
                    }
                }
                
                form.getImportGroups().addAll(changedGroups);

                // LastChangerId aktualisieren
                iterUser = form.getImportUser().iterator();
                
                while (iterUser.hasNext()) {
                    VKCUser user = (VKCUser) iterUser.next();
                    
                    if (VKCUserSerializer.isUserExistent(user.getUser())) {
                        user.setLastChanged(new Timestamp(System.currentTimeMillis()));
                        user.setLastChangerId(form.getUser().getUserId());
                    } else if (form.getUserIds().containsKey(user.getLastChangerId())) {
                        user.setLastChangerId((Integer) form.getUserIds().get(user.getLastChangerId()));
                    } else {
                        user.setLastChanged(new Timestamp(System.currentTimeMillis()));
                        user.setLastChangerId(form.getUser().getUserId());
                    }
                    if(!VKCUserSerializer.isUserExistent(user.getUser())){
                        if(form.getUserIds().containsKey(user.getCreatorId()) ){
                            user.setCreatorId((Integer) form.getUserIds().get(user.getCreatorId()));
                        }else{
                            user.setCreated(new Timestamp(System.currentTimeMillis()));
                            user.setCreatorId(form.getUser().getUserId());
                        }
                    }
                }
                // Veraltete Informationen von Kategorien rausfiltern
                Iterator iterCategories = form.getImportCategories().iterator();

                while (iterCategories.hasNext()) {
                    VKCCategory category = (VKCCategory) iterCategories.next();
                    VKCDynaAttribute alteId = new VKCDynaAttribute();
                    alteId.setName("Id before migration");
                    alteId.setValue(category.getCategoryId().toString());
                    Integer newId = DBHelper.getNewId(conn, "Categories", "categoryId");
                    category.getDynaAttributes().add(alteId);
                    form.getCategoryIds().put(category.getCategoryId(), newId);
                    form.getCategoryIdsReverse().put(newId, category.getCategoryId());
                    category.setCategoryId(newId);

                    if (category.getLastAccessorId() != null && form.getUserIds().containsKey(category.getLastAccessorId())) {
                        category.setLastAccessorId((Integer) form.getUserIds().get(category.getLastAccessorId()));
                    } else {
                        category.setLastAccessorId(null);
                        category.setLastAccessed(null);
                    }
                    
                    if (category.getLastChangerId() != null && form.getUserIds().containsKey(category.getLastChangerId())) {
                        category.setLastChangerId((Integer) form.getUserIds().get(category.getLastChangerId()));
                    } else {
                        category.setLastChanged(null);
                        category.setLastChangerId(null);
                    }
                    
                    if (category.getCreatorId() != null && form.getUserIds().containsKey(category.getCreatorId())) {
                        category.setCreatorId((Integer) form.getUserIds().get(category.getCreatorId()));
                    }

                    // Zugriffsrechte im Bezug auf Benutzer- und GruppenIds
                    // aktualisieren
                    VKCAcl acl = category.getAcl();
                    acl.setAclId(null);
                    Iterator iterAclEntries = acl.getAclEntries().iterator();

                    while (iterAclEntries.hasNext()) {
                        VKCAclEntry entry = (VKCAclEntry) iterAclEntries.next();
                        
                        if (form.getUserIds().containsKey(entry.getCreatorId())) {
                            entry.setCreatorId((Integer) form.getUserIds().get(entry.getCreatorId()));
                        } else {
                            entry.setCreatorId(form.getUser().getUserId());
                        }
                        
                        if (entry.getAclType().getName().equals(VKCAclType.GROUP)) {
                            if (form.getGroupIds().containsKey(entry.getAccessorId())) {
                                entry.setAccessorId((Integer) form.getGroupIds().get(entry.getAccessorId()));
                            } else {
                                iterAclEntries.remove();
                            }
                        }
                        
                        if (entry.getAclType().getName().equals(VKCAclType.USER)) {
                            if (form.getUserIds().containsKey(entry.getAccessorId())) {
                                entry.setAccessorId((Integer) form.getUserIds().get(entry.getAccessorId()));
                            } else {
                                iterAclEntries.remove();
                            }
                        }
                        
                        if (entry.getAclType().getName().equals(VKCAclType.OWNER)) {
                            if (form.getUserIds().containsKey(entry.getAccessorId())) {
                                entry.setAccessorId((Integer) form.getUserIds().get(entry.getAccessorId()));
                            } else {
                                iterAclEntries.remove();
                            }
                        }
                        // Diese Version unterstützt keinen Export für LDAPUsers
                        // oder LDAPGroups
                        if (entry.getAclType().getName().equals(VKCAclType.LDAP_GROUP)) {
                            iterAclEntries.remove();
                        }
                        
                        if (entry.getAclType().getName().equals(VKCAclType.LDAP_USER)) {
                            iterAclEntries.remove();
                        }
                    }

                    if (category.getCreatorId() != null && form.getUserIds().containsKey(category.getCreatorId())) {
                        category.setCreatorId((Integer) form.getUserIds().get(category.getCreatorId()));
                    } else {
                        category.setCreatorId(form.getUser().getUserId());
                        category.setCreated(new Date());
                    }

                }

                iterCategories = form.getImportCategories().iterator();
                
                while (iterCategories.hasNext()) {
                    VKCCategory cat = (VKCCategory) iterCategories.next();
                    // falls ParentCategory nicht existiert oder wurde nicht
                    // exportiert->cat ist oberste Category
                    if (cat.getParentCategoryId() == null || !form.getCategoryIds().containsKey(cat.getParentCategoryId())) {
                        root = cat;
                        cat.setParentCategoryId(form.getCategoryId());
                    } else {
                        cat.setParentCategoryId((Integer) form.getCategoryIds().get(cat.getParentCategoryId()));
                    }
                    // SubCategoriesId aktualisieren
                    Iterator iterSubCat = cat.getSubCategories().iterator();
                    
                    while (iterSubCat.hasNext()) {
                        VKCSubCategory subCat = ((VKCSubCategory) iterSubCat.next());
                        subCat.setSubCategoryId((Integer) form.getCategoryIds().get(subCat.getSubCategoryId()));
                    }

                    cat.setDocuments(new ArrayList());
                }
                // Dokumente importieren
                Iterator iterDocuments = form.getImportDocuments().iterator();
                
                while (iterDocuments.hasNext()) {
                    VKCDocument doc = (VKCDocument) iterDocuments.next();
                    VKCDynaAttribute alteId = new VKCDynaAttribute();
                    alteId.setName("Id before migration");
                    alteId.setValue(doc.getDocumentId().toString());
                    doc.addDynaAttribute(alteId);
                    Integer oldId = doc.getDocumentId();
                    Integer newId = DBHelper.getNewId(conn, "Documents", "DocumentId");
                    form.getDocumentIds().put(doc.getDocumentId(), newId);
                    doc.setDocumentId(newId);
                    // zusätzliche Formate auf null setzen
                    doc.setAdditionalDocumentFormats(new ArrayList());

                    if (doc.getLastAccessorId() != null && form.getUserIds().containsKey(doc.getLastAccessorId())) {
                        doc.setLastAccessorId((Integer) form.getUserIds().get(doc.getLastAccessorId()));
                    } else {
                        doc.setLastAccessorId(null);
                        doc.setLastAccessed(null);
                    }
                    
                    if (doc.getLastChangerId() != null && form.getUserIds().containsKey(doc.getLastChangerId())) {
                        doc.setLastChangerId((Integer) form.getUserIds().get(doc.getLastChangerId()));
                    } else {
                        doc.setLastChanged(null);
                        doc.setLastChangerId(null);
                    }

                    if (doc.getPublisherId() != null && form.getUserIds().containsKey(doc.getPublisherId())) {
                        doc.setPublisherId((Integer) form.getUserIds().get(doc.getPublisherId()));
                    } else {
                        doc.setPublished(new Date());
                        doc.setPublisherId(form.getUser().getUserId());
                    }

                    if (doc.getCategoryId() != null) {
                        doc.setCategoryId((Integer) form.getCategoryIds().get(doc.getCategoryId()));
                    }
                    
                    String docTypeExtension = doc.getDocumentType().getExtension();
                    
                    if (doc.isFile()) {
                        String pfad = null;
                        
                        if (doc.getCategoryId() != null) {
                            pfad = form.getPath(doc.getCategoryId().intValue());
                        } else {
                            VKCDynaAttribute attr = doc.getDynaAttribute("CategoryId");
                            
                            if (attr != null) {
                                pfad = form.getPath(((Integer) form.getCategoryIds().get(new Integer(attr.getValue()))).intValue());
                                doc.getDynaAttributes().remove(attr);
                            }
                        }

                        File tempFile = null;
                        String fileName = ArchiveCategory.docName2PathName(doc.getName());
                        int i = fileName.lastIndexOf('.');
                        
                        if (i > -1) {
                            if (fileName.endsWith(".")) {
                                fileName = fileName + "-Version-" + doc.getVersionNo()+"-Id-"+oldId;
                            } else {
                                fileName = fileName.substring(0, i) + "-Version-" + doc.getVersionNo() +"-Id-"+oldId+"."
                                        + (docTypeExtension.equals("?") ? fileName.substring(i, fileName.length()) : docTypeExtension);
                            }
                        } else {
                            fileName = fileName + "-Version-" + doc.getVersionNo()+"-Id-"+oldId;
                        }
                        
                        tempFile = new File(pfad, VKCStringUtils.decodeXmlEntities(fileName));
                        FileInputStream is = null;
                        
                        try {
                            is = new FileInputStream(tempFile);
                            doc.setArchiveId(WebShare.archive.store(is));
                            is.close();
                        } catch (FileNotFoundException e) {
                            // Inhalt des Dokumentes nicht gefunden => leere
                            // Datei erzeugen

                            doc.setArchiveId(WebShare.archive.store(new FileInputStream(File.createTempFile("LeereDatei", null))));
                        }
                    }
                }

                iterDocuments = form.getImportDocuments().iterator();
                
                while (iterDocuments.hasNext()) {
                    VKCDocument doc = (VKCDocument) iterDocuments.next();
                    // Bei versionierten Dokumenten die Ids von Dokumenten
                    // aktualisieren
                    if (doc.getPreDocId() != null && form.getDocumentIds().containsKey(doc.getPreDocId())) {
                        doc.setPreDocId((Integer) form.getDocumentIds().get(doc.getPreDocId()));
                    }
                }

                iterUser = form.getImportUser().iterator();
                
                while (iterUser.hasNext()) {
                    VKCUser user = (VKCUser) iterUser.next();
                    
                    if (form.getCategoryIds().containsKey(user.getHomeCategoryId())) {
                        user.setHomeCategoryId((Integer) form.getCategoryIds().get(user.getHomeCategoryId()));
                    } else {
                        user.setHomeCategoryId(null);
                    }
                }

                String dateString = new SimpleDateFormat("-yyyy-MM-dd-kk-mm-ss").format(new Date());
                String name = root.getName() + "_migration_von" + dateString;
                VKCDynaAttribute alterName = new VKCDynaAttribute();
                alterName.setName("Name before migration");
                alterName.setValue(root.getName());
                root.getDynaAttributes().add(alterName);
                root.setName(name);

                VKCMigrationObjects migObjects = readObjects(form);
                iterCategories = migObjects.getMigrationCategories().iterator();
                VKCLogManager.migrationLog(this, "following categories will be imported");
                
                while (iterCategories.hasNext()) {
                    VKCCategory expCat = (VKCCategory) iterCategories.next();
                    VKCCategory impCat = null;
                    Iterator iterImpCategories = form.getImportCategories().iterator();
                    
                    while (iterImpCategories.hasNext()) {
                        impCat = (VKCCategory) iterImpCategories.next();
                        
                        if (form.getCategoryIds().get(expCat.getCategoryId()).equals(impCat.getCategoryId())) {
                            break;
                        }
                    }
                    
                    VKCLogManager.migrationLog(expCat, "Export id " + expCat.getCategoryId() + " export name: " + expCat.getName() + " to import id " + impCat.getCategoryId() + " import name: "
                            + impCat.getName());
                }

                iterDocuments = migObjects.getMigrationDocuments().iterator();
                VKCLogManager.migrationLog(this, "following documents will be imported");
                
                while (iterDocuments.hasNext()) {
                    VKCDocument expDoc = (VKCDocument) iterDocuments.next();
                    VKCDocument impDoc = null;
                    Iterator iterImpDocuments = form.getImportDocuments().iterator();
                    
                    while (iterImpDocuments.hasNext()) {
                        impDoc = (VKCDocument) iterImpDocuments.next();
                        
                        if (form.getDocumentIds().get(expDoc.getDocumentId()).equals(impDoc.getDocumentId())) {
                            break;
                        }
                    }
                    
                    VKCLogManager.migrationLog(expDoc, "Export id " + expDoc.getDocumentId() + " export name: " + expDoc.getDisplayName() + " to import id " + impDoc.getDocumentId()
                            + " import name: " + impDoc.getDisplayName());
                }

                iterGroups = migObjects.getMigrationGroups().iterator();
                VKCLogManager.migrationLog(this, "following groups will be imported");
                
                while (iterGroups.hasNext()) {
                    VKCGroup expGroup = (VKCGroup) iterGroups.next();
                    VKCGroup impGroup = null;
                    Iterator iterImpGroups = form.getImportGroups().iterator();
                    
                    while (iterImpGroups.hasNext()) {
                        impGroup = (VKCGroup) iterImpGroups.next();
                        
                        if (form.getGroupIds().get(expGroup.getGroupId()).equals(impGroup.getGroupId())) {
                            break;
                        }
                    }
                    
                    VKCLogManager.migrationLog(expGroup, "Export id " + expGroup.getGroupId() + " export name: " + expGroup.getName() + " to import id " + impGroup.getGroupId() + " import name: "
                            + impGroup.getName());
                }

                iterUser = migObjects.getMigrationUsers().iterator();
                VKCLogManager.migrationLog(this, "following users will be imported");
                
                while (iterUser.hasNext()) {
                    VKCUser expUser = (VKCUser) iterUser.next();
                    VKCUser impUser = null;
                    Iterator iterImpUser = form.getImportUser().iterator();
                    
                    while (iterImpUser.hasNext()) {
                        impUser = (VKCUser) iterImpUser.next();
                        
                        if (form.getUserIds().get(expUser.getUserId()).equals(impUser.getUserId())) {
                            break;
                        }
                    }

                    VKCLogManager.migrationLog(expUser, "Export id " + expUser.getUserId() + " export name:" + expUser.getFullName() + " to import id " + impUser.getUserId() + " import name:"
                            + impUser.getFullName());

                }
                // alles speichern
                if (form.getImportGroups() != null) {
                    VKCGroupSerializer.importGroup(new ArrayList(form.getImportGroups()), conn);
                }
                
                if (form.getImportUser() != null) {
                    VKCUserSerializer.importUser(new ArrayList(form.getImportUser()), conn);
                }
                
                ArrayList list = new ArrayList();
                form.sortSet(root, list);

                VKCCategorySerializer.importCategory(list, conn);
                
                if (form.getImportDocuments() != null) {
                    VKCDocumentSerializer.importDocument(new ArrayList(form.getImportDocuments()), conn);
                }
                // Alle Kategorieanfragen aktualisieren und speichern
                Iterator iterQuery = form.getImportQueries().keySet().iterator();
                
                while (iterQuery.hasNext()) {
                    Integer id = (Integer) iterQuery.next();
                    VKCSearchQuery query = form.getImportQueries().get(id);
                    
                    if (id != null && id.intValue() > 0) {
                        if (form.getCategoryIds().containsKey(id)) {
                            Integer selectedId = new Integer(query.getSelectedCategoryId());
                            
                            if (form.getCategoryIds().containsKey(selectedId)) {
                                Integer selectedCategoryId = (Integer) form.getCategoryIds().get(selectedId);
                                query.setSelectedCategoryId(selectedCategoryId.toString());
                            } else {
                                query.setSelectedCategoryId(new Integer(VKCCategory.ROOT_CATEGORY_ID).toString());
                            }
                            
                            Integer newId = (Integer) form.getCategoryIds().get(id);
                            VKCCategorySerializer.saveSearchQuery(query, newId, conn);
                        }
                    }
                }

                // Alle registrierte Anfragen von Benutzer aktualisieren und
                // speichern
                iterQuery = form.getImportUserQueries().iterator();
                
                while (iterQuery.hasNext()) {
                    VKCSearchQuery query = (VKCSearchQuery) iterQuery.next();
                    
                    if (form.getUserIds().containsKey(query.getUserId())) {
                        query.setUserId((Integer) form.getUserIds().get(query.getUserId()));
                        VKCUserRegSearchQuerySerializer.saveSearchQuery(query, query.getUserId(), conn);
                    }
                }

                // Mails wegen hinzugekommenen Dokumenten organisieren
                iterDocuments = form.getImportDocuments().iterator();
                
                while (iterDocuments.hasNext()) {
                    if (WebShare.docPublishMail.isEnabled()) {
                        UserDocMailsPopulator.getInstance().addForPopulation((VKCDocument) iterDocuments.next());
                    }
                }
                
                conn.commit();
                VKCLogManager.migrationLog(this, "Import completed successfully");

                request.setAttribute("succeeded", form.getResources().getMessage(form.getLocale(), "vkc.administration.systemmaintenance.import.importSucceded"));

                // die Zugangsdaten zuschicken
                String notSended = "";
                Iterator userIter = notSendedForUser.iterator();
                while (userIter.hasNext()) {
                    VKCUser user = (VKCUser) userIter.next();
                    try {
                        String senderAddr = VKCSysParameterSerializer.retrieveValue("MAIL", "AdminEmail", "");
                        String smtpServer = VKCSysParameterSerializer.retrieveValue("MAIL", "MailServer", "");
                        String smtpUsername = VKCSysParameterSerializer.retrieveValue("MAIL", "MailUsername", "");
                        String smtpPassword = VKCSysParameterSerializer.retrieveValue("MAIL", "MailPassword", "");
                        String vkc_rootURL = WebShare.getRootURL() + WebShare.getContextPath();
                        String subject = WebShare.resources.getMessage(user.getLanguage().getLocale(), "vkc.changepassword");
                        String recepient = VKCStringUtils.decodeXmlEntities(user.getEmail());

                        TemplateParser asciiTemplate = TemplateParser.getTemplateParser();
                        TemplateParser htmlTemplate = TemplateParser.getTemplateParser();

                        HashMap context = new HashMap();
                        context.put("adminEmail", senderAddr);
                        context.put("homepage", vkc_rootURL);
                        context.put("username", VKCStringUtils.filterUnicodeChars(user.getUser()));
                        context.put("fullname", VKCStringUtils.filterUnicodeChars(user.getFirstname() + " " + user.getLastname()));
                        context.put("password", user.getClearPassword());
                        context.put("resources", new ResourceInfo(WebShare.resources, user.getLanguage().getLocale()));
                        context.put("vkcstringutils", new VKCStringUtils());
                        context.put("template", user.getTemplate().getName());

                        asciiTemplate.setContextData(context);
                        htmlTemplate.setContextData(context);
                        String asciiPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.plain";
                        String htmlPath = "templates/${template.name}/velocitytemplates/mail/changepassword_notification.html";

                        String asciiText = asciiTemplate.createString(ServletUtils.replacePathVars(asciiPath, user));
                        String htmlText = htmlTemplate.createString(ServletUtils.replacePathVars(htmlPath, user));

                        MailUtils m = new MailUtils(user);
                        if(user.isEnableHtmlNotification())m.sendSMTPMailWithVKCLogo(senderAddr, recepient, subject, asciiText, htmlText, null, null, smtpServer, smtpUsername, smtpPassword);
                        else m.sendSMTPMail(senderAddr, recepient, subject, asciiText, null, null, null, smtpServer, smtpUsername, smtpPassword);
                    } catch (Exception e) {
                        notSended += user.getFullName() + "    ";
                        VKCLogManager.errorLog(this, "1", " - email sending failes: " + e.getMessage(), e);
                    }
                }
                
                if (!StringUtils.isEmpty(notSended)) {
                    ActionErrors errors = new ActionErrors();
                    errors.add("mailmessage.failure", new ActionError("error.import.mailfailed", notSended));
                    request.setAttribute(Globals.ERROR_KEY, errors);
                }
            } catch (Exception e) {
                VKCLogManager.errorLog(e.getClass(), "", e.getMessage(), e);
                VKCLogManager.migrationLog(e, e.getMessage());
                e.printStackTrace();
                DBHelper.rollBack(conn);

                // Mögliche Änderungen am Treeview zurücksetzen
                TreeViewManager.getInstance().requestUpdate();
            } finally {
                // Dateien löschen
                rootName = form.getCategoryIdsReverse().get(root.getCategoryId()).toString();
                
                if (rootName != null && !rootName.equals("")) {
                    FileUtils.deleteDirectory(new File(form.getArchiveDirectoryPath() + File.separator + ArchiveCategory.catName2PathName(VKCStringUtils.decodeXmlEntities(rootName))));
                }
                
                if (form.getPathForObjects() != null) {
                    new File(form.getPathForObjects()).delete();
                }
            } 
           
            DBHelper.close(conn);
            Iterator iterDoc = form.getImportDocuments().iterator();
            
            while (iterDoc.hasNext()) {
                VKCDocument doc = (VKCDocument) iterDoc.next();

                if (doc.getDocumentType().isConvertible()) {
                    // Erzeugung der zusätzlichen Dokumentformate anstossen
                    ConversionStatus s = new ConversionStatus();
                    s.setDocumentId(doc.getDocumentId());
                    s.setSendmail(false);
                    s.makePersistent();
                }
            }
        }
    }

    private VKCMigrationObjects readObjects(ImportMaintenanceForm form) {
        File objects = new File(form.getPathForObjects());
        FileInputStream fis;
        // ObjectInputStream o;

        try {
            fis = new FileInputStream(objects);
            XStream xstream = new XStream();
            VKCMigrationObjects migObj = ((VKCMigrationObjects) xstream.fromXML(fis));
            fis.close();
            
            return migObj;
        } catch (FileNotFoundException e) {
            VKCLogManager.errorLog(this, "1", "Can't find the importfile!", e);
            VKCLogManager.migrationLog(this, "Can't find the importfile!");
        } catch (IOException e) {
            VKCLogManager.errorLog(this, "2", "Exception by read importfile!", e);
            VKCLogManager.migrationLog(e, "Exception by read importfile!");
        }
        
        return null;
    }
}