/*
 * $Id: VKCUser.java,v 1.81 2008/02/12 09:39:46 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: VKCUser.java,v $
 * Revision 1.81  2008/02/12 09:39:46  korowa
 * + Eine Möglichkeit für den Benutzer hinzugefügt die Emailsart auszuwählen (HTML oder Plaintext)
 * + Betreff für den Messenger der als Emailsubject bei Benachrichtigung übers erscheinen von VKC Dokumenten verschickt wird.
 *
 * Revision 1.80  2007/11/02 19:52:20  marbobo
 * + Bugfix (Statt List werden HashSet benutzt)
 *
 * Revision 1.79  2007/08/08 12:14:50  marbobo
 * + License-Funktionalität komplett umgeschrieben
 * + Bugfix bzgl. Beschreibungsfelder von Entitäten
 * + Bugfix mailing
 *
 * Revision 1.78  2006/11/06 10:44:44  korowa
 * Attribute und Zugriffsfunktionen für akzeptierte Lizenz und Zeitpunkt des Akzeptierens hinzugefügt
 *
 * Revision 1.77  2006/10/04 03:15:18  marbobo
 * + Vollständige Unterstützung für Templates implementiert
 * + Alles von Virtoweb auf ProCoBa umgestellt
 *
 * Revision 1.76  2006/09/13 08:14:55  lawern
 * Für korowa eingecheckt.
 *
 * Revision 1.75  2006/09/03 18:00:16  marbobo
 * + addDynaAttribute() korrigiert
 *
 * Revision 1.74  2006/09/01 11:04:15  korowa
 * +addDynaAttribute(VKCDynUserAttribute dynaAttribute) Neue Funktion hinzugefügt die es erlaubt ein Dyn.Attribut zu der Liste Dyn. Attributen hinzufügen.
 *
 * Revision 1.73  2006/05/12 08:09:07  korowa
 * +showTree zum Userprofil hinzugefügt. Dieser parameter regelt die Anzeige des Explorerfensters beim VKC-Anmeldung. Lässt sich im Userprofil umschalten.
 *
 * Revision 1.72  2006/04/29 18:39:48  marbobo
 * + Refactoriengs und eine Ausgaben vereinheitlicht
 *
 * Revision 1.71  2006/03/23 11:39:33  marbobo
 * + Bugfix
 *
 * Revision 1.70  2006/02/27 16:16:06  marbobo
 * + Systemsichten hinzugefügt
 * + SysLinks angepasst
 * + Benutzer können falls gewünscht Dokumentqueries anlegen
 *
 * Revision 1.69  2005/11/24 01:26:04  marbobo
 * + Begrenzung von Fehlversuchen bei Passworteingabe und Sperrung von Benutzer eingebaut (beide sind Konfigurierbar)
 *
 * Revision 1.68  2005/09/15 13:41:16  marbobo
 * + Sprachabhängige Sortierung implementiert
 *
 * Revision 1.67  2005/09/07 22:05:17  marbobo
 * + Sortierung in der Bestseller-Liste standardmäßig auf Absteigend nach Zugriffen gesetzt
 *
 * Revision 1.66  2005/09/07 13:51:02  marbobo
 * + Sortierung nach Erstellungsdatum implementiert
 *
 * Revision 1.65  2005/04/28 15:27:49  korowa
 * Die Sortierungs Methoden werden jetzt im Profil in Datenbank gespeichert
 *
 * Revision 1.64  2005/03/16 15:42:54  jonyp
 * added getLastnameLabel method
 *
 * Revision 1.63  2005/02/15 09:26:47  bigmac
 * Refactorings
 *
 * Revision 1.62  2004/12/16 13:18:22  jonyp
 * +MostRecentLogout
 *
 * Revision 1.61  2004/12/09 15:20:38  jonyp
 * change from VKCLanguage.getDefault to VKCLangaugeSerializer.getDefaultLanguage
 *
 * Revision 1.60  2004/12/03 15:29:36  jonyp
 * delete VKCUser(e, p, ...) constructor, added some javadoc
 *
 * Revision 1.59  2004/12/03 15:20:44  jonyp
 * deleted method getAttributes ==> obsolete !!!
 *
 * Revision 1.58  2004/11/22 14:41:31  vchris
 * MessagingTimePeriod mit Standardwert besetzt
 *
 * Revision 1.57  2004/11/19 16:06:55  jonyp
 * added userrating
 *
 * Revision 1.56  2004/11/02 21:39:35  marbobo
 * + Gast-Benutzerkennung : userId = -1
 *
 * Revision 1.55  2004/10/31 02:56:30  marbobo
 * - AdminPrivilegesByGroupValid()
 *
 * Revision 1.54  2004/10/24 18:18:20  marbobo
 * + getAdminPrivilegesByGroupValid()
 *
 * Revision 1.53  2004/10/22 15:25:45  jonyp
 * added support fields for external auth-servers
 *
 * Revision 1.52  2004/10/15 15:14:37  jonyp
 * added external... variables to use with externalAuthServers
 *
 * Revision 1.51  2004/10/14 10:13:56  jonyp
 * delete final attribute from class
 *
 * Revision 1.50  2004/08/26 22:09:54  marbobo
 * + Query bezogene Methoden überarbeitet
 *
 * Revision 1.49  2004/08/20 12:39:09  koppy
 * +registeredQueries, clearPassword
 *
 * Revision 1.48  2004/07/23 14:53:25  jonyp
 * changed methos signature retrieveNews(int) to retrieveNews()
 *
 * Revision 1.47  2004/07/23 10:17:24  jonyp
 * + deleted wrong comment
 * + rename method isUnreadedNews to hasUnreadNews
 * 
 *
 * Revision 1.45  2004/07/22 22:07:38  marbobo
 * + isUnreadedNews()
 *
 * Revision 1.44  2004/07/21 14:16:33  jonyp
 * added column for user: mostrecentnews
 *
 * Revision 1.43  2004/07/02 13:17:01  marbobo
 * - letzte Änderung wieder Rückgängig gemacht
 *
 * Revision 1.42  2004/07/02 12:59:28  marbobo
 * + getAdminPrivilegesByGroup() angepasst
 *
 * Revision 1.41  2004/07/02 09:27:34  jonyp
 * added "isNormalUser" method
 *
 * Revision 1.40  2004/07/01 11:27:40  jonyp
 * added getUserTypeIcon
 *
 * Revision 1.39  2004/06/27 17:16:54  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.38  2004/06/15 20:22:21  marbobo
 * Refactoring
 *
 * Revision 1.37  2004/05/15 17:01:48  marbobo
 * isDedicatedAdmin() -> isDedicatedUsersAdmin() oder isDedicatedGroupsAdmin()
 * + isAdmin() und isAdminByGroup()
 *
 * Revision 1.35  2004/03/30 13:17:12  jonyp
 * track homeCategoryId
 *
 * Revision 1.34  2004/03/26 08:23:36  bigmac
 * Kein caching mehr von ProjectInfos
 *
 * Revision 1.33  2004/03/18 01:22:02  marbobo
 * + getGroupIds()
 *
 * Revision 1.32  2004/03/13 20:46:16  bigmac
 * Weitere Refactorings ...
 *
 * Revision 1.31  2004/03/12 15:44:17  bigmac
 * Methoden für (lokale) zusätzliche Attribute aus VKCDynAttributeSerializer 
 * nach VKCAddAttributeSerializer verschoben
 * 
 * Unbenutze private Methoden projektweit entsorgt
 *
 * Revision 1.30  2004/03/08 18:22:50  bigmac
 * Anpassungen an VKCLanguageSerializer
 *
 * Revision 1.29  2004/03/07 20:05:57  bigmac
 * einige Methoden aus der VKCDataBase in die entsprechenden 
 * Serializer verschoben, ein paar Refactorings durchgeführt und 
 * tote Code-Teile entfernt
 *
 * Revision 1.28  2004/02/10 14:47:51  bigmac
 * +getProjectInfos()
 *
 * Revision 1.27  2004/02/09 20:45:53  bigmac
 * +getHasAdminPrivileges für struts
 *
 * Revision 1.26  2004/01/26 13:53:15  marbobo
 * + isDedicatedAdmin()
 *
 * Revision 1.25  2003/12/18 18:49:54  bigmac
 * Überflüssige Imports gelöscht
 *
 * Revision 1.24  2003/12/02 15:03:22  bigmac
 * Default Vor- und Nachname des Gastusers geändert
 *
 * Revision 1.23  2003/12/02 09:47:07  jonyp
 * default quota
 *
 * Revision 1.22  2003/11/28 15:04:10  jonyp
 * changes due to new schema
 *
 * Revision 1.21  2003/11/21 14:19:46  bigmac
 * Usertracking erweitert
 *
 * Revision 1.20  2003/11/12 16:31:35  bigmac
 * Usertracking überarbeitet
 *
 * Revision 1.19  2003/11/01 00:34:41  marbobo
 * + valueBound und valueUnbound() wieder hinzugefügt
 *
 * Revision 1.18  2003/10/31 17:49:19  marbobo
 * - valueBound und valueUnbound() entfernt, weil fälschlicherweise Benutzer
 *  als angemeldet angezeigt wurden die nicht angemeldet waren (die beiden
 *  Methoden wurden bei jedem retrieveUser() aufgerufen)
 *
 * Revision 1.16  2003/10/23 21:35:00  marbobo
 * Aufgeräumt
 *
 * Revision 1.15  2003/10/17 00:50:26  marbobo
 * + Speed-Up beim User-Objekt(reg. Dokumente und Kategorien)
 *
 * Revision 1.14  2003/10/06 10:20:57  bigmac
 * createGuestUser() added
 *
 */
package vkc.db.entities;

import java.io.Serializable;
import java.sql.Timestamp;
import java.text.CollationKey;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import vkc.db.serializer.VKCCategorySerializer;
import vkc.db.serializer.VKCLanguageSerializer;
import vkc.db.serializer.VKCDocumentSerializer;
import vkc.db.serializer.VKCLicenseSerializer;
import vkc.db.serializer.VKCNewsSerializer;
import vkc.db.serializer.VKCTemplateSerializer;
import vkc.db.serializer.VKCUserRatingSerializer;
import vkc.db.serializer.VKCUserRegSearchQuerySerializer;
import vkc.exception.DBException;
import vkc.security.Accessor;
import vkc.util.ObjectCloner;
import vkc.util.ProjectUtils;
import vkc.util.StringUtils;
import vkc.util.VKCStringUtils;
import vkc.util.sort.ProjectInfoSortFactory;
import vkc.view.PageId;
import vkc.view.WebShare;
import vkc.view.bean.RegisteredCategory;
import vkc.view.bean.RegisteredDocument;
import vkc.view.form.ShowBestsellerForm;
import vkc.view.form.ShowCategoryForm;
import vkc.view.form.ShowLatestAdditionsForm;

/**
 * This Class represents a user-entity of the VKC system
 *
 */
public class VKCUser extends VKCEntity implements Accessor, 
												  Cloneable,
                                                  Serializable {
    // constants
    public final static Integer SYSTEM_USER_ID = new Integer(0);
    public final static Integer ADMIN_USER_ID = new Integer(1);
    
    private boolean accountValid = true; 
	private boolean adminPrivileges = false;	
	private boolean manageOwnGroups = false;
	private boolean manageOwnUsers = false;
	private boolean manageOwnUsersSystemViews = false;
	private boolean manageOwnProxies = false;
	private boolean manageVirtualDocumentQueries = false;
	private boolean messagingEnabled = true;
	private boolean passwordChanged	= false;
	private boolean showEmail = true;
	private boolean allowManageSystemViewType = false;
	private boolean showTree = false;
    private boolean enableHtmlNotification = false;

	private Integer creatorId;
	private Integer homeCategoryId = new Integer(VKCCategory.ROOT_CATEGORY_ID); // default home category = root category !!!
	private Integer languageId = VKCEntity.ID_UNDEFINED;
	private Integer lastChangerId;
	private Integer messagingTimePeriod = new Integer (15);
	private Integer quota = new Integer(50);  // default quota
	private Integer sessionTimeout = new Integer(60); // default session timeout in minutes
	private Integer templateId = VKCEntity.ID_UNDEFINED;
	private Integer userId = VKCEntity.ID_UNDEFINED;
    private Integer searchDocumentSortMode		= new Integer(1);
    private Integer bestsellerDocumentSortMode	= new Integer(ShowBestsellerForm.DOCUMENT_SORT_ACCESSCOUNT_DOWN);
    private Integer latestAdditionsDocumentSortMode	= new Integer(ShowLatestAdditionsForm.DOCUMENT_SORT_PUBLISHING_DATE_DOWN);
    private Integer categoryViewDocumentSortMode	= new Integer(ShowCategoryForm.DOCUMENT_SORT_PUBLISHING_DATE_DOWN);
    private Integer pwdMismatchCount = new Integer(0);
    private Integer systemViewTypeId = PageId.CATEGORY_VIEW;

	private HashMap registeredCategories = new HashMap();
	private HashMap registeredDocuments = new HashMap();
	private HashMap registeredQueries = new HashMap();

	private Set groups = new HashSet();

	private String city = "";
	private String company = "";
	private String contactURL = "";
	private String department = "";
	private String email = "";
	private String fax = "";
	private String firstname = "";
	private String homepageURL = "";
	private String lastname = "";
	private String mobile = "";
	private String password = "";
	private String clearPassword = "";
	private String phone = "";
	private String title = "";
	private String street = "";
	private String urls = "";
	private String user = "";
	private String zip = "";    

	private Timestamp created = new Timestamp(System.currentTimeMillis());
	private Timestamp lastChanged = new Timestamp(System.currentTimeMillis());
	private Timestamp mostRecentLogin;
	private Timestamp mostRecentLogout;
	private Timestamp mostRecentNews;
    private Timestamp passwordChangedTs; 
    private Timestamp validFrom;
    private Timestamp validUntil;
    
    // things for referring external users
    private String externalUserId = null;
    private String externalServerType = "";
    private Integer externalServerId = null;

	private VKCLanguage language = null;
	
	private VKCUserRating rating = null;

    /**
     * Default constructor
     *
     */
	public VKCUser() {
    	setLanguage(VKCLanguageSerializer.getDefaultLanguage());
    }

	/**
	 * Method creates an anonymous guest user.
	 * 
	 */
	public final static VKCUser createGuestUser() {
		VKCUser guest = new VKCUser();
		guest.setUser("guest");
		guest.setAccountValid(true);
		guest.setMessagingEnabled(false);
		guest.setFirstname("Guest");
		guest.setLastname("User");
		
		return guest;
	}

	/**
	 * Checks if current user is a "guest user"
	 * 
	 * @return true: yes: guest user; no: no guest user
	 */
	public boolean isGuestUser() {
		return getUserId().equals(VKCEntity.ID_UNDEFINED);
	}

	/**
	 * Set user's title
	 * 
	 * @param title
	 */	
    public void setTitle(String s) {
        title = StringUtils.normalize(s);
    }

	/**
	 * Get user's title
	 * 
	 * @return title of user
	 */    
    public String getTitle() {
        return title;
    }

	public void setPassword(String s) {
		password = StringUtils.normalize(s);
	}

	public String getPassword() {
		return password;
	}

    public void setFax(String s) {
        fax = StringUtils.normalize(s);
    }

    public String getFax() {
        return fax;
    }

    public void setFirstname(String s) {
        firstname = StringUtils.normalize(s);
    }

    public String getFirstname() {
        return firstname;
    }

	public void setLastname(String s) {
		lastname = StringUtils.normalize(s);
	}

	public String getLastname() {
		return lastname;
	}

	public void setMobile(String s) {
		mobile = StringUtils.normalize(s);
	}

	public String getMobile() {
		return mobile;
	}

	public void setContactURL(String s) {
		contactURL = StringUtils.normalize(s);
	}

	public String getContactURL() {
		return contactURL;
	}

	public void setHomepageURL(String s) {
		homepageURL = StringUtils.normalize(s);
	}

	public String getHomepageURL() {
		return homepageURL;
	}

	public void setPhone(String s) {
		phone = StringUtils.normalize(s);
	}

	public String getPhone() {
		return phone;
	}

	public void setStreet(String s) {
		street = StringUtils.normalize(s);
	}

	public String getStreet() {
		return street;
	}

	public void setUser(String s) {
		user = StringUtils.normalize(s);
	}

	public String getUser() {
		return user;
	}

	public void setZip(String s) {
		zip = StringUtils.normalize(s);
	}

	public String getZip() {
		return zip;
	}

	public void setCity(String s) {
		city = StringUtils.normalize(s);
	}

	public String getCity() {
		return city;
	}

	public void setCompany(String s) {
		company = StringUtils.normalize(s);
	}

	public String getCompany() {
		return company;
	}

	public void setDepartment(String s) {
		department = StringUtils.normalize(s);
	}

	public String getDepartment() {
		return department;
	}

	public void setEmail(String s) {
		email = StringUtils.normalize(s);
	}

	public String getEmail() {
		return email;
	}

	public String getUrls() {
		return urls;
	}

	public void setUrls(String s) {
		urls = StringUtils.normalize(s);
	}

    public void setKeywordsString(String s) {
        super.setKeywordsByString(StringUtils.normalize(s));
    }

	public String getKeywordsString() {
		return super.getKeywordsAsString();
	}

	public void setLanguage(VKCLanguage l) {
		if (l == null) {
			l = VKCLanguageSerializer.getDefaultLanguage();
		}

		language = l;
		languageId = l.getLanguageId();
	}

	public VKCLanguage getLanguage() {
		return language;
	}

    public void setMessagingEnabled(boolean b) {
        messagingEnabled = b;
    }

    public boolean getMessagingEnabled() {
        return messagingEnabled;
    }

    public void setAdminPrivileges(boolean b) {
        adminPrivileges = b;
    }

    public boolean getAdminPrivileges() {
        return adminPrivileges;
    }

    public boolean getAdminPrivilegesByGroup() {
        if (getGroups() == null) {
            return false;
        }
        
        Iterator itGroups = getGroups().iterator();

		while (itGroups.hasNext()) {
			VKCGroup group = (VKCGroup)itGroups.next();
			
			if (group.getAdminPrivileges().booleanValue() && group.isGroupValid().booleanValue()) {
				return true;
			}
		}

        return false;
    }

	public boolean hasAdminPrivileges(){
		return getAdminPrivileges() || getAdminPrivilegesByGroup();
	}

    public boolean getHasAdminPrivileges(){
        return hasAdminPrivileges();
    }

	public boolean isDedicatedGroupsAdmin(){
		return !hasAdminPrivileges() && manageOwnGroups;
	}

	public boolean isDedicatedUsersAdmin(){
		return !hasAdminPrivileges() && manageOwnUsers;
	}
	
	public boolean isDedicatedAdmin() {
		return isDedicatedGroupsAdmin() || isDedicatedUsersAdmin();
	}
	
	public boolean isAdmin() {
		return getAdminPrivileges();
	}
	
	public boolean isAdminByGroup() {
		return !isAdmin() && getAdminPrivilegesByGroup();
	}

    public boolean isNormalUser() {
    	if (hasAdminPrivileges() || isDedicatedAdmin()) {
    		return false;
    	}
    	
    	return true; 
    }

	public void setManageOwnProxies(boolean b) {
		manageOwnProxies = b;
	}

	public boolean getManageOwnProxies() {
		return manageOwnProxies;
	}

    public void setManageOwnGroups(boolean b) {
        manageOwnGroups = b;
    }

    public boolean getManageOwnGroups() {
        return manageOwnGroups;
    }

	public void setManageOwnUsers(boolean b) {
		manageOwnUsers = b;
	}

	public boolean getManageOwnUsers() {
		return manageOwnUsers;
	}

    public Integer getSessionTimeout() {
        return sessionTimeout;    	
    }

	public void setSessionTimeout(Integer i) {
		sessionTimeout = i;
	}

	public Integer getQuota() {
		return quota;    	
	}

	public void setQuota(Integer i) {
		quota = i;
	}

    public void setCreated(Timestamp t) {
        created = t;
    }

    public Timestamp getCreated() {
        return created;
    }

    public void setCreatorId(Integer i) {
        creatorId = i;
    }

    public Integer getCreatorId() {
        return creatorId;
    }

    public void setLastChanged(Timestamp t) {
        lastChanged = t;
    }

    public Timestamp getLastChanged() {
        return lastChanged;
    }

    public void setLastChangerId(Integer i) {
        lastChangerId = i;
    }

    public Integer getLastChangerId() {
        return lastChangerId;
    }

    public void setMessagingTimePeriod(Integer i) {
        messagingTimePeriod = i;
    }

    public Integer getMessagingTimePeriod() {
        return messagingTimePeriod;
    }

    public void setPasswordChanged(boolean b) {
        passwordChanged = b;
    }

    public boolean isPasswordChanged() {
        return passwordChanged;
    }

    public void setShowEmail(boolean b) {
        showEmail = b;
    }

    public boolean getShowEmail() {
        return showEmail;
    }
    
    public void setUserId(Integer i) {
        userId = i;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setValidFrom(Timestamp t) {
        validFrom = t;
    }

    public Timestamp getValidFrom() {
        return validFrom;
    }

    public void setValidUntil(Timestamp t) {
        validUntil = t;
    }

    public Timestamp getValidUntil() {
        return validUntil;
    }

    public boolean addGroup(VKCGroup g) {
        return getGroups().add(g);
    }

    public boolean removeGroup(VKCGroup g) {
        return getGroups().remove(g);
    }

    public Integer getAccessorId() {
        return getUserId();
    }

    public String getAccessorName() {
        return getUser();
    }

	public String getFullName() {
		return getLastname() + ", " + getFirstname() + " (" + getUser() + ")";
	}

	public String toString() {
		return getLastname() + ", " + getFirstname() + " (" + getUser() + ")";
	}

    public boolean isMemberOf(Integer groupId) {
        Iterator it = getGroups().iterator();

        while (it.hasNext()) {
            VKCGroup g = (VKCGroup) it.next();

            if (g.getGroupId().intValue() == groupId.intValue()) {
                return true;
            }
        }

        return false;
    }

    public VKCUser cloneUser() throws Exception {
        return (VKCUser) ObjectCloner.deepCopy(this);
    }

	public Timestamp getPasswordChangedTs() {
		return passwordChangedTs;
	}

	public void setPasswordChangedTs(Timestamp t) {
		passwordChangedTs = t;
	}

	public void setAccountValid(boolean b) {
		accountValid = b;
	}

	public boolean getAccountValid() {
		return accountValid;
	}

	public boolean isUserValid(){
		Timestamp today = new Timestamp(System.currentTimeMillis());

		if (getAccountValid()) {
			if (getValidFrom() != null && getValidUntil() == null) {
				if (getValidFrom().before(today)) {
					return getAccountValid();			
				} 

				return false;
			} else if (getValidFrom() == null && getValidUntil() != null) {
				if (getValidUntil().after(today)) {
					return getAccountValid();			
				} 

				return false;
			} else if (getValidFrom() != null && getValidUntil() != null) {
				if (getValidFrom().before(today) && getValidUntil().after(today)) {
					return getAccountValid();			
				} 

				return false;
			} else{
				return getAccountValid();
			}
		} 

		return getAccountValid();
	}

    public Integer getTemplateId() {
        return templateId;
    }

    public void setTemplateId(Integer i) {
        templateId = i;
    }
    
    public VKCTemplate getTemplate() {
        VKCTemplate template = VKCTemplateSerializer.getTemplateById(getTemplateId());

        if (template == null) {
            template = new VKCTemplate();
            template.setName(WebShare.DEFAULT_TEMPLATE);
            template.setPath("/templates");
            template.setDescription("default template");
            template.setPreviewPicture("/templates/" + WebShare.DEFAULT_TEMPLATE + "/gfx/defaultlayout.jpg");
        }

        return template;
    }
    
	public void setRegisteredCategories(HashMap map) {
		registeredCategories = map;
	}

	public HashMap getRegisteredCategories() {
		return registeredCategories;
	}
	
	public boolean addRegisteredCategory(RegisteredCategory category) {
		if (!getRegisteredCategories().containsKey(category.getCategoryId())) {
			getRegisteredCategories().put(category.getCategoryId(), category);

			return true;
		}

		return false;
	}
	
	public boolean removeRegisteredCategory(RegisteredCategory category) {
		if (getRegisteredCategories().containsKey(category.getCategoryId())) {
			getRegisteredCategories().remove(category.getCategoryId());
	
			return true;
		} 

		return false;
	}

	public boolean isRegisteredCategory(Integer categoryId) {
		if (getRegisteredCategories().containsKey(categoryId)) {
			return true;
		} 

		return false;
	}

	public void retrieveRegisteredCategories() throws DBException {
		registeredCategories = VKCCategorySerializer.retrieveUserRegisteredCategories(getUserId());
	}
	
	public void saveRegisteredCategories() throws DBException {
        VKCCategorySerializer.saveUserRegisteredCategories(this);
	}

	public List getRegisteredCategoriesSortedByName() {
		final Collator collator = Collator.getInstance(getLanguage().getLocale());

		Comparator name_c = new Comparator() {
			public int compare(Object o1, Object o2) {
				RegisteredCategory c1 = (RegisteredCategory)o1;
				RegisteredCategory c2 = (RegisteredCategory)o2;
				
            	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getName()));
            	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getName()));
            	
            	return key1.compareTo(key2);
			}
		};
		
		List c = new ArrayList(getRegisteredCategories().values());
		Collections.sort(c, name_c);
		
		return c;
	}

	public List getRegisteredCategoriesSortedByPath() {
		final Collator collator = Collator.getInstance(getLanguage().getLocale());

		Comparator path_c = new Comparator() {
			public int compare(Object o1, Object o2) {
				RegisteredCategory c1 = (RegisteredCategory)o1;
				RegisteredCategory c2 = (RegisteredCategory)o2;
				
            	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c1.getAbsPathDescr().getAbsolutePathString()));
            	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(c2.getAbsPathDescr().getAbsolutePathString()));
            	
            	return key1.compareTo(key2);
			}
		};
		
		List c = new ArrayList(getRegisteredCategories().values());
		Collections.sort(c, path_c);
		
		return c;
	}

	public void setRegisteredDocuments(HashMap map) {
		registeredDocuments = map;
	}

	public HashMap getRegisteredDocuments() {
		return registeredDocuments;
	}

	public boolean addRegisteredDocument(RegisteredDocument document) {
		if (!getRegisteredDocuments().containsKey(document.getDocumentId())) {
			getRegisteredDocuments().put(document.getDocumentId(), document);
			
			return true;
		} 

		return false;
	}
	
	public boolean removeRegisteredDocument(RegisteredDocument document) {
		if (getRegisteredDocuments().containsKey(document.getDocumentId())) {
			getRegisteredDocuments().remove(document.getDocumentId());
	
			return true;
		} 

		return false;
	}

	public boolean isRegisteredDocument(Integer documentId) {
		if (getRegisteredDocuments().containsKey(documentId)) {
		    return true;
		} 

		return false;
	}

	public void retrieveRegisteredDocuments() throws DBException {
		registeredDocuments = VKCDocumentSerializer.retrieveUserRegisteredDocuments(getUserId());
	}
	
	public void saveRegisteredDocuments() throws DBException {
        VKCDocumentSerializer.saveUserRegisteredDocuments(this);
	}

	public List getRegisteredDocumentsSortedByName() {
		final Collator collator = Collator.getInstance(getLanguage().getLocale());

		Comparator name_d = new Comparator() {
			public int compare(Object o1, Object o2) {
				RegisteredDocument d1 = (RegisteredDocument)o1;
				RegisteredDocument d2 = (RegisteredDocument)o2;
				
            	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getName()));
            	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getName()));
            	
            	return key1.compareTo(key2);
			}
		};
		
		List d = new ArrayList(getRegisteredDocuments().values());
		Collections.sort(d, name_d);

		return d;
	}

	public List getRegisteredDocumentsSortedByTitle() {
		final Collator collator = Collator.getInstance(getLanguage().getLocale());

		Comparator title_d = new Comparator() {
			public int compare(Object o1, Object o2) {
				RegisteredDocument d1 = (RegisteredDocument)o1;
				RegisteredDocument d2 = (RegisteredDocument)o2;
				
            	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d1.getTitle()));
            	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(d2.getTitle()));
            	
            	return key1.compareTo(key2);
			}
		};
		
		List d = new ArrayList(getRegisteredDocuments().values());
		Collections.sort(d, title_d);
	
		return d;
	}

	public HashMap getRegisteredQueries() {
	    return registeredQueries;
	}

	public void setRegisteredQueries(HashMap queries){
	    registeredQueries = queries;
	}
	
	public boolean addRegisteredQuery(VKCSearchQuery query) {
		if (!getRegisteredQueries().containsKey(query.getQueryId())) {
			getRegisteredQueries().put(query.getQueryId(), query);
			
			return true;
		} 

		return false;
	}
	
	public boolean removeRegisteredQuery(VKCSearchQuery query) {
		if (getRegisteredQueries().containsKey(query.getQueryId())) {
			getRegisteredQueries().remove(query.getQueryId());
	
			return true;
		} 

		return false;
	}

	public boolean isRegisteredQuery(Integer queryId) {
		if (getRegisteredQueries().containsKey(queryId)) {
		    return true;
		} 

		return false;
	}

	public void retrieveRegisteredQueries() throws DBException {
		registeredQueries = VKCUserRegSearchQuerySerializer.retrieveSearchQueries(getUserId());
	}
	
	public void saveRegisteredQueries() throws DBException {
        VKCUserRegSearchQuerySerializer.saveSearchQueries(getRegisteredQueries().values(), getUserId());
	}

    public List getRegisteredQueriesSortedBy(){
        return new ArrayList(getRegisteredQueries().values());
    }

    public void setGroups(Set g) {
		groups = g;
	}

	public Set getGroups() {
		return groups;
	}
	
	public List getGroupIds() {
		List ids = new ArrayList();
		
		for (Iterator it = getGroups().iterator(); it.hasNext();) {
			VKCGroup g = (VKCGroup)it.next();
			ids.add(g.getGroupId());
		}
		
		return ids;
	}

	public List getGroupsSortedByName() {
		final Collator collator = Collator.getInstance(getLanguage().getLocale());

		Comparator name_c = new Comparator() {
			public int compare(Object o1, Object o2) {
				VKCGroup g1 = (VKCGroup)o1;
				VKCGroup g2 = (VKCGroup)o2;
				
            	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g1.getName()));
            	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g2.getName()));
            	
            	return key1.compareTo(key2);
			}
		};
		
		List g = new ArrayList(getGroups());
		Collections.sort(g, name_c);
		
		return g;
	}

	public String getGroupsString() {
		String   groupsStr = "";
		Iterator iter = getGroups().iterator();

		while (iter.hasNext()) {
			VKCGroup group = (VKCGroup) iter.next();
			groupsStr += group.getName();
			groupsStr += WebShare.GROUPS_DELIMITER;
		}

		return groupsStr;
	}
	
	public List getProjectInfos() throws DBException {
		List projectInfos = ProjectUtils.getProjectInfos(this); 
		ProjectInfoSortFactory.sort(projectInfos, ProjectInfoSortFactory.SORT_BY_NAME_UP);

		return projectInfos;
	}

	public Integer getLanguageId() {
		return languageId;
	}

	public void setLanguageId(Integer i) {
		languageId = i;
	}
	
	public Integer getHomeCategoryId() {
		return homeCategoryId;
	}

	public void setHomeCategoryId(Integer i) {
		homeCategoryId = i;
	}

	public Timestamp getMostRecentLogout() {
		return mostRecentLogout;
	}

	public void setMostRecentLogout(Timestamp timestamp) {
		mostRecentLogout = timestamp;
	}
	
	public Timestamp getMostRecentLogin() {
		return mostRecentLogin;
	}

	public void setMostRecentLogin(Timestamp timestamp) {
		mostRecentLogin = timestamp;
	}
	
	public Timestamp getMostRecentNews() {
		return mostRecentNews;
	}

	public void setMostRecentNews(Timestamp timestamp) {
		mostRecentNews = timestamp;
	}	

	public boolean hasUnreadNews() throws DBException {
	    List news = VKCNewsSerializer.retrieveNews();

	    if (getMostRecentNews() != null) {
	        for (int i = 0; i < news.size(); i++) {
	            VKCNews n = (VKCNews)news.get(i);
	            
	            if (n.getValidFrom() != null && n.getValidUntil() != null) {
	                Timestamp now = new Timestamp(System.currentTimeMillis());
	                boolean b1 = now.after(n.getValidFrom());
	                boolean b2 = now.before(n.getValidUntil());
	                
	                if (b1 && b2 && getMostRecentNews().before(n.getValidFrom())) {
	                    return true;
	                }
	            } else if (n.getValidFrom() == null && n.getValidUntil() != null) {
	                Timestamp now = new Timestamp(System.currentTimeMillis());
	                boolean b1 = now.after(n.getCreated());
	                boolean b2 = now.before(n.getValidUntil());
	                
	                if (b1 && b2 && getMostRecentNews().before(n.getCreated())) {
	                    return true;
	                }
	            } else if (n.getValidFrom() != null) {
	                Timestamp now = new Timestamp(System.currentTimeMillis());
	                boolean b1 = now.after(n.getValidFrom());
	                
	                if (b1 && getMostRecentNews().before(n.getValidFrom())) {
	                    return true;
	                }
	            } else if (getMostRecentNews().before(n.getCreated())) {
	                return true;
	            }
	        }
	        
	        return false;
	    }
	    
        for (int i = 0; i < news.size(); i++) {
            VKCNews n = (VKCNews)news.get(i);
            
            if (n.getValidFrom() != null && n.getValidUntil() != null) {
                Timestamp now = new Timestamp(System.currentTimeMillis());
                boolean b1 = now.after(n.getValidFrom());
                boolean b2 = now.before(n.getValidUntil());
                
                if (b1 && b2) {
                    return true;
                }
            } else if (n.getValidFrom() == null && n.getValidUntil() != null) {
                Timestamp now = new Timestamp(System.currentTimeMillis());
                boolean b1 = now.after(n.getCreated());
                boolean b2 = now.before(n.getValidUntil());
                
                if (b1 && b2) {
                    return true;
                }
            } else if (n.getValidFrom() != null) {
                Timestamp now = new Timestamp(System.currentTimeMillis());
                boolean b1 = now.after(n.getValidFrom());
                
                if (b1) {
                    return true;
                }
            } else {
                return true;
            }
        }

        return false;
	}
	
	public String getUserTypeIcon() {
        if (hasAdminPrivileges()) {
            return "profile-admin.gif";
        }
            
        if (isDedicatedAdmin()) {
        	return "profile-dadmin.gif";
        }
		
        if (isExternalUser()) {
            return "profile-external.gif";
        }
		
        return "profile.gif";
	}

    public String getClearPassword() {
        return clearPassword;
    }

    public void setClearPassword(String clearPwd) {
        clearPassword = clearPwd;
    }

    public Integer getExternalServerId() {
        return externalServerId;
    }

    public void setExternalServerId(Integer i) {
        externalServerId = i;
    }

    public String getExternalServerType() {
        return externalServerType;
    }

    public void setExternalServerType(String s) {
        externalServerType = StringUtils.normalize(s);
    }

    public String getExternalUserId() {
        return externalUserId;
    }

    public void setExternalUserId(String s) {
        externalUserId = StringUtils.normalize(s);
    }
    
    public boolean isExternalUser() {
        if (getExternalServerId() != null) {
            return true;
        }
       
        return false;        
    }
    
    public String getUserDescription() {
        return "User '" + getUser() + "'";
    }
    
    public VKCUserRating getRating() throws DBException{
        if (rating == null) {
            rating = VKCUserRatingSerializer.retrieveRating(getUserId());
        } 
        
        return rating;
    }
    
    public final String getLastnameLabel() {
        return getLastname() + ", " + getFirstname() + " (" + getUser() + ")";
    }
    
    public Integer getBestsellerDocumentSortMode() {
        return bestsellerDocumentSortMode;
    }

    public void setBestsellerDocumentSortMode(Integer bestsellerDocumentSortMode) {
        this.bestsellerDocumentSortMode = bestsellerDocumentSortMode;
    }

    public Integer getCategoryViewDocumentSortMode() {
        return categoryViewDocumentSortMode;
    }

    public void setCategoryViewDocumentSortMode(Integer categoryViewDocumentSortMode) {
        this.categoryViewDocumentSortMode = categoryViewDocumentSortMode;
    }

    public Integer getLatestAdditionsDocumentSortMode() {
        return latestAdditionsDocumentSortMode;
    }

    public void setLatestAdditionsDocumentSortMode(Integer latestAdditionsDocumentSortMode) {
        this.latestAdditionsDocumentSortMode = latestAdditionsDocumentSortMode;
    }

    public Integer getSearchDocumentSortMode() {
        return searchDocumentSortMode;
    }

    public void setSearchDocumentSortMode(Integer searchDocumentSortMode) {
        this.searchDocumentSortMode = searchDocumentSortMode;
    }

	public Integer getPwdMismatchCount() {
		return pwdMismatchCount;
	}

	public void setPwdMismatchCount(Integer pwdMismatchCount) {
		this.pwdMismatchCount = pwdMismatchCount;
	}

	public boolean isAllowManageSystemViewType() {
		return allowManageSystemViewType;
	}

	public void setAllowManageSystemViewType(boolean allowManageSystemViewType) {
		this.allowManageSystemViewType = allowManageSystemViewType;
	}

	public Integer getSystemViewTypeId() {
		return systemViewTypeId;
	}

	public void setSystemViewTypeId(Integer systemViewTypeId) {
		this.systemViewTypeId = systemViewTypeId;
	}

	public boolean isManageOwnUsersSystemViews() {
		return manageOwnUsersSystemViews;
	}

	public void setManageOwnUsersSystemViews(boolean manageOwnUsersSystemViews) {
		this.manageOwnUsersSystemViews = manageOwnUsersSystemViews;
	}

	public boolean isManageVirtualDocumentQueries() {
		return manageVirtualDocumentQueries;
	}

	public void setManageVirtualDocumentQueries(boolean manageVirtualDocumentQueries) {
		this.manageVirtualDocumentQueries = manageVirtualDocumentQueries;
	}

	public boolean getShowTree() {
		return showTree;
	}

	public void setShowTree(boolean showTree) {
		this.showTree = showTree;
	}

	public boolean addDynaAttribute(VKCDynUserAttribute dynaAttribute) {
		return getDynaAttributes().add(dynaAttribute);
	}
	
    /**
	 * Gibt das dynamische Attribute zurück
	 * @param attrName
	 * @return
	 */
	public VKCDynUserAttribute getDynUserAttribute(String attrName) {
		for (Iterator iter = this.getDynaAttributes().iterator(); iter.hasNext();) {
            VKCDynUserAttribute da = (VKCDynUserAttribute) iter.next();
            
            if (da.getName().equals(attrName)) {
                return da;
            }
        }
		
		return null;
	}
	
	public VKCDynUserAttribute getDynUserAttribute(String attrName, String attrValue) {
		for (Iterator iter = this.getDynaAttributes().iterator(); iter.hasNext();) {
            VKCDynUserAttribute da = (VKCDynUserAttribute) iter.next();
            
            if (da.getName().equals(attrName) && da.getValue().equals(attrValue)) {
                return da;
            }
        }
		
		return null;
	}
    
    public List getLicense() throws DBException {
        return VKCLicenseSerializer.retrieveUserLicense(getUserId());
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        
        if (obj instanceof VKCUser) {
            VKCUser user = (VKCUser) obj;
            
            return getUserId().equals(user.getUserId());
        }
        
        return false;
    }

    public boolean isEnableHtmlNotification() {
        return enableHtmlNotification;
    }

    public void setEnableHtmlNotification(boolean enableHtmlNotification) {
        this.enableHtmlNotification = enableHtmlNotification;
    }

}