/*
 * $Id: VKCProjectSubfolderDAO.java,v 1.8 2007/02/13 12:28:38 lawern Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
 * THIS SOFTWARE OR ITS DERIVATIVES.
 *
 * $Log: VKCProjectSubfolderDAO.java,v $
 * Revision 1.8  2007/02/13 12:28:38  lawern
 * Delegator-Konstruktor-Methoden nur noch friendly oder private.
 *
 * Revision 1.7  2007/01/09 11:56:27  korowa
 * VKCExternalException wird nicht mehr abgefangen sondern weitergereicht
 *
 * Revision 1.6  2007/01/02 11:08:43  jonyp
 * delete unnecessary ";"
 *
 * Revision 1.5  2006/10/04 03:14:53  marbobo
 * + Vollständige Unterstützung für Templates implementiert
 * + Alles von Virtoweb auf ProCoBa umgestellt
 *
 * Revision 1.4  2006/09/15 09:03:31  lawern
 * Javadoc-Anpassungen
 *
 * Revision 1.3  2006/09/14 09:04:33  lawern
 * DB-Persistenz nur noch nach .save-Aufruf
 *
 * Revision 1.2  2006/09/13 09:32:46  lawern
 * allgemeine Überarbeitung
 *
 * Revision 1.1  2006/08/24 14:51:42  marbobo
 * + Initiale Version
 *
 */
package vkc.external;

import java.io.InputStream;
import java.sql.Timestamp;
import java.util.Set;

import javax.servlet.http.HttpSession;

import vkc.db.entities.VKCAclType;
import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCAclSerializer;
import vkc.db.serializer.VKCCategorySerializer;
import vkc.exception.DBException;
import vkc.procoba.project.entities.VKCProjectSubfolder;
import vkc.security.PermissionManager;
import vkc.security.VKCAcl;
import vkc.util.VKCStringUtils;
import vkc.view.WebShare;

/**
 * Diese Klasse kapselt ein im VKC-System liegendes Projektordner. Mit Hilfe der
 * Methoden dieser Klasse können vorhandene Projektordner geholt und bestimmte
 * Metadaten verändert werden. Ebenso können auch neue Projektordner angelegt
 * werden.
 * 
 * @author marbobo
 */
public class VKCProjectSubfolderDAO {
	VKCCategoryDAO internalCategoryDAO = new VKCCategoryDAO();

	VKCProjectSubfolderDAO() {
		try {
			internalCategoryDAO.internalCategory = new VKCProjectSubfolder();
			internalCategoryDAO.internalCategory.setName("");
			internalCategoryDAO.internalCategory.setDescription("");
			internalCategoryDAO.internalCategory
					.setParentCategoryId(new Integer(
							VKCCategory.ROOT_CATEGORY_ID));
			VKCAcl acl = VKCAclSerializer
					.getAclByCategoryId(internalCategoryDAO.internalCategory
							.getParentCategoryId());
			acl.setAclId(null);
			internalCategoryDAO.internalCategory.setAcl(acl);
		} catch (DBException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Konstruktor zum Anlegen eines neuen Projektunterordners
	 * 
	 * @param name
	 *            Name des Projektunterordners
	 * @param description
	 *            Beschreibung des Projektunterordners
	 * @param parentCategoryId
	 *            ID der übergeordneten Kategorie
	 */
	public VKCProjectSubfolderDAO(String name, String description,
			Integer parentCategoryId) {
		try {
			internalCategoryDAO.internalCategory = new VKCProjectSubfolder();

			if (name != null) {
				internalCategoryDAO.internalCategory.setName(VKCStringUtils
						.filterUnicodeChars(name));
			} else {
				internalCategoryDAO.internalCategory.setName("");
			}

			if (description != null) {
				description = VKCStringUtils.filterUnicodeChars(description);
				description = VKCStringUtils.decodeXmlEntities(description);
				description = VKCStringUtils
						.encodeNamedXmlEntities(description);
				internalCategoryDAO.internalCategory
						.setDescription(description);
			} else {
				internalCategoryDAO.internalCategory.setDescription("");
			}

			if (parentCategoryId != null) {
				internalCategoryDAO.internalCategory
						.setParentCategoryId(parentCategoryId);
			} else {
				internalCategoryDAO.internalCategory
						.setParentCategoryId(new Integer(
								VKCCategory.ROOT_CATEGORY_ID));
			}

			VKCAcl acl = VKCAclSerializer
					.getAclByCategoryId(internalCategoryDAO.internalCategory
							.getParentCategoryId());
			acl.setAclId(null);
			internalCategoryDAO.internalCategory.setAcl(acl);
		} catch (DBException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Konstruktor zum Anlegen eines neuen Projektunterordners aus einem
	 * regulären VKC ProjektSubfolder-Objekt
	 * 
	 * @param projectSubfolder
	 *            Regulärer VKC Projektunterordner
	 */
	VKCProjectSubfolderDAO(VKCProjectSubfolder projectSubfolder) {
		internalCategoryDAO.internalCategory = projectSubfolder;
	}

	/**
	 * Liefert für eine Projektunterordner-ID und einen Benutzer das
	 * Projektunterordner-Objekt zurück
	 * 
	 * @param projectSubfolderId
	 *            ID des Projektunterordners, das geholt werden soll
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @return Das gewünschte Projektunterordner-Objekt, falls der Benutzer die
	 *         entsprechenden Rechte hat, null sonst
	 * @throws VKCExternalException 
	 */
	public static VKCProjectSubfolderDAO retrieveVKCProjectSubfolderDAO(
			Integer projectSubfolderId, HttpSession session) throws VKCExternalException {
		return retrieveVKCProjectSubfolderDAO(projectSubfolderId,
				(VKCUser) session.getAttribute(WebShare.USER_KEY));
	}

	/**
	 * Liefert für eine Projektunterordner-ID und einen Benutzer das
	 * Projektunterordner-Objekt zurück
	 * 
	 * @param projectSubfolderId
	 *            ID des Projektunterordners, das geholt werden soll
	 * @param user
	 *            Der aktuelle Benutzer
	 * @return Das gewünschte Projektunterordner-Objekt, falls der Benutzer die
	 *         entsprechenden Rechte hat, null sonst
	 * @throws VKCExternalException 
	 */
	public static VKCProjectSubfolderDAO retrieveVKCProjectSubfolderDAO(
			Integer projectSubfolderId, VKCUserDAO user) throws VKCExternalException {
		if (user.isAuthorized()) {
			return retrieveVKCProjectSubfolderDAO(projectSubfolderId, user
					.getIntUser());
		}

		return null;
	}

	/**
	 * Liefert für eine Projektunterordner-ID und einen Benutzer das
	 * Projektunterordner-Objekt zurück
	 * 
	 * @param projectSubfolderId
	 *            ID des Projektunterordners, das geholt werden soll
	 * @param user
	 *            Der aktuelle Benutzer
	 * @return Das gewünschte Projektunterordner-Objekt, falls der Benutzer die
	 *         entsprechenden Rechte hat, null sonst
	 * @throws VKCExternalException 
	 */
	private static VKCProjectSubfolderDAO retrieveVKCProjectSubfolderDAO(
			Integer projectSubfolderId, VKCUser user) throws VKCExternalException {
		if (user == null) {
			return null;
		}

		VKCProjectSubfolder projectSubfolder = null;

		try {
			if (PermissionManager.hasPermission(VKCAclSerializer
					.getAclByCategoryId(projectSubfolderId), user, 'r')) {
				VKCCategory category = VKCCategorySerializer
						.retrieveCategory(projectSubfolderId);

				if (category instanceof VKCProjectSubfolder) {
					projectSubfolder = (VKCProjectSubfolder) category;
				}

				if (projectSubfolder != null) {
					return new VKCProjectSubfolderDAO(projectSubfolder);
				}

				throw new VKCExternalException(VKCExternalException.UNKNOWN);
			}

			throw new VKCExternalException(
					VKCExternalException.READ_PERMISSION_FAILED);
		} catch (DBException e) {
			e.printStackTrace();

			return null;
		}
	}

	/**
	 * Fügt diesem Projektunterordner ein Dokument hinzu
	 * 
	 * @param document
	 *            Hinzufügendes Dokument
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#addDocument(vkc.external.VKCDocumentDAO,
	 *      javax.servlet.http.HttpSession)
	 */
	public void addDocument(VKCDocumentDAO document, HttpSession session) throws VKCExternalException {
		internalCategoryDAO.addDocument(document, session);
	}

	/**
	 * Fügt diesem Projektunterordner ein Dokument mit dem angegebenem
	 * InputStream hinzu
	 * 
	 * @param document
	 *            Hinzufügendes Dokument
	 * @param docStream
	 *            InputStream des Dokuments
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#addDocument(vkc.external.VKCDocumentDAO,
	 *      java.io.InputStream, javax.servlet.http.HttpSession)
	 */
	public void addDocument(VKCDocumentDAO document, InputStream docStream,
			HttpSession session) throws VKCExternalException {
		internalCategoryDAO.addDocument(document, docStream, session);
	}

	/**
	 * Fügt diesem Projektunterordner ein Dokument mit dem angegebenem
	 * InputStream hinzu
	 * 
	 * @param document
	 *            Hinzufügendes Dokument
	 * @param docStream
	 *            InputStream des Dokuments
	 * @param user
	 *            Benutzer-Objekt
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#addDocument(vkc.external.VKCDocumentDAO,
	 *      java.io.InputStream, vkc.external.VKCUserDAO)
	 */
	public void addDocument(VKCDocumentDAO document, InputStream docStream,
			VKCUserDAO user) throws VKCExternalException {
		internalCategoryDAO.addDocument(document, docStream, user);
	}

	/**
	 * Fügt diesem Projektunterordner ein Dokument hinzu
	 * 
	 * @param document
	 *            Hinzufügendes Dokument
	 * @param user
	 *            Benutzer-Objekt
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#addDocument(vkc.external.VKCDocumentDAO,
	 *      vkc.external.VKCUserDAO)
	 */
	public void addDocument(VKCDocumentDAO document, VKCUserDAO user) throws VKCExternalException {
		internalCategoryDAO.addDocument(document, user);
	}

	/**
	 * Fügt diesem Projektunterordner ein dynamisches Attribut hinzu
	 * 
	 * @param dynaAttribute
	 *            Hinzufügendes Attribute
	 * @see vkc.external.VKCCategoryDAO#addDynaAttribute(vkc.external.VKCDynaAttributeDAO)
	 */
	public void addDynaAttribute(VKCDynaAttributeDAO dynaAttribute) {
		internalCategoryDAO.addDynaAttribute(dynaAttribute);
	}

	/**
	 * Fügt diesem Projektunterordner eine Unterkategorie hinzu
	 * 
	 * @param subCategory
	 *            Hinzuzufügende Unterkategorie
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 */
	public void addSubCategory(VKCProjectSubfolderDAO subCategory,
			HttpSession session) throws VKCExternalException {
		addSubCategory(subCategory, (VKCUser) session
				.getAttribute(WebShare.USER_KEY));
	}

	/**
	 * Fügt diesem Projektunterordner eine Unterkategorie hinzu
	 * 
	 * @param subCategory
	 *            Hinzuzufügende Unterkategorie
	 * @param user
	 *            Benutzer-Objekt
	 * @throws VKCExternalException 
	 */
	public void addSubCategory(VKCProjectSubfolderDAO subCategory,
			VKCUserDAO user) throws VKCExternalException {
		addSubCategory(subCategory, user.getIntUser());
	}

	/**
	 * Fügt diesem Projektunterordner eine Unterkategorie hinzu
	 * 
	 * @param subCategory
	 *            Hinzuzufügende Unterkategorie
	 * @param user
	 *            Benutzer-Objekt
	 * @throws VKCExternalException 
	 */
	private void addSubCategory(VKCProjectSubfolderDAO subCategory, VKCUser user) throws VKCExternalException {
		if (subCategory == null) {
			return;
		}

		if (internalCategoryDAO.internalCategory.getCategoryId() != null) {
			try {
				if (PermissionManager.hasPermission(
						internalCategoryDAO.internalCategory.getAcl(), user,
						'C')) {
					VKCAcl acl = internalCategoryDAO.internalCategory.getAcl();

					try {
						PermissionManager.setCategoryOwnerPermissions(
								new Integer(VKCAclType.USER_TYPE), user
										.getUserId(), user.getUserId(), acl);
					} catch (Exception ex) {
					}

					acl.setAclId(null);

					VKCCategory newCategory = subCategory.internalCategoryDAO.internalCategory;
					newCategory.setAcl(acl);
					newCategory
							.setParentCategoryId(internalCategoryDAO.internalCategory
									.getCategoryId());
					newCategory.setCreated(new Timestamp(System
							.currentTimeMillis()));
					newCategory.setCreatorId(user.getUserId());
					// Fügt die Kategorie ein
					VKCCategorySerializer.saveCategory(newCategory);
				} else {
					throw new VKCExternalException(
							VKCExternalException.CREATE_CATEGORY_PERMISSION_FAILED);
				}
			} catch (DBException e) {
				e.printStackTrace();
			}
		} else {
			throw new VKCExternalException(VKCExternalException.ID_MISSED);
		}
	}

	/**
	 * Löscht dieses Projektunterordner
	 * 
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#delete(javax.servlet.http.HttpSession)
	 */
	public void delete(HttpSession session) throws VKCExternalException {
		internalCategoryDAO.delete(session);
	}

	/**
	 * Löscht dieses Projektunterordner
	 * 
	 * @param user
	 *            Benutzer-Objekt
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#delete(vkc.external.VKCUserDAO)
	 */
	public void delete(VKCUserDAO user) throws VKCExternalException {
		internalCategoryDAO.delete(user);
	}

	/**
	 * Löscht das dynamische Attribute mit dem angegebenen Namen
	 * 
	 * @param name
	 *            Der Name des Attributes
	 * @see vkc.external.VKCCategoryDAO#deleteDynaAttribute(java.lang.String)
	 */
	public void deleteDynaAttribute(String name) {
		internalCategoryDAO.deleteDynaAttribute(name);
	}

	/**
	 * Liefert für das aktuelle Projektunterordner alle vom Benutzer lesbaren
	 * direkten Unterkategorie IDs zurück
	 * 
	 * @param user
	 *            Der aktuelle Benutzer
	 * @return <code>Set</code> der Unterkategorie IDs
	 * @see vkc.external.VKCCategoryDAO#getAccessibleSubCategoryIds(vkc.external.VKCUserDAO)
	 */
	public Set getAccessibleSubCategoryIds(VKCUserDAO user) {
		return internalCategoryDAO.getAccessibleSubCategoryIds(user);
	}

	/**
	 * Liefert die ID dieses Projektunterordners
	 * 
	 * @return Die Projekt ID
	 * @see vkc.external.VKCCategoryDAO#getCategoryId()
	 */
	public Integer getCategoryId() {
		return internalCategoryDAO.getCategoryId();
	}

	/**
	 * Liefert die ID des Projektes an dem dieses Projektunterordners hängt
	 * 
	 * @return Die Projekt ID
	 */
	public Integer getProjectId() {
		return ((VKCProjectSubfolder) internalCategoryDAO.internalCategory)
				.getProjectId();
	}

	/**
	 * Liefert die Beschreibung dieses Projektunterordners (in Unicode) zurück
	 * 
	 * @return Die Beschreibung dieses Projektunterordners (in Unicode)
	 * @see vkc.external.VKCCategoryDAO#getDescription()
	 */
	public String getDescription() {
		return internalCategoryDAO.getDescription();
	}

	/**
	 * Liefert für das aktuelle Projektunterordner alle Dokument IDs zurück
	 * 
	 * @return <code>Set</code> der Dokument IDs
	 * @see vkc.external.VKCCategoryDAO#getDocumentIds()
	 */
	public Set getDocumentIds() {
		return internalCategoryDAO.getDocumentIds();
	}

	/**
	 * Gibt das dynamische Attribute zurück
	 * 
	 * @param name
	 *            Der Name des Attributes
	 * @return Falls vorhanden das dynamische Attribut, sonst null
	 * @see vkc.external.VKCCategoryDAO#getDynaAttribute(java.lang.String)
	 */
	public VKCDynaAttributeDAO getDynaAttribute(String name) {
		return internalCategoryDAO.getDynaAttribute(name);
	}

	/**
	 * Liefert den Namen dieses Projektunterordners (in Unicode) zurück
	 * 
	 * @return Der Name dieses Projektunterordners (in Unicode)
	 * @see vkc.external.VKCCategoryDAO#getName()
	 */
	public String getName() {
		return internalCategoryDAO.getName();
	}

	/**
	 * Liefert die Eltern-Kategorie ID
	 * 
	 * @return Die Eltern-Kategorie ID
	 * @see vkc.external.VKCCategoryDAO#getParentCategoryId()
	 */
	public Integer getParentCategoryId() {
		return internalCategoryDAO.getParentCategoryId();
	}

	/**
	 * Liefert für das aktuelle Projektunterordner alle direkten Unterkategorie
	 * IDs zurück
	 * 
	 * @return <code>Set</code> der Unterkategorie IDs
	 * @see vkc.external.VKCCategoryDAO#getSubCategoryIds()
	 */
	public Set getSubCategoryIds() {
		return internalCategoryDAO.getSubCategoryIds();
	}

	/**
	 * Liefert für das aktuelle Projektunterordner rekursiv alle Unterkategorie
	 * IDs zurück
	 * 
	 * @return <code>Set</code> der Unterkategorie IDs
	 * @throws DBException
	 * @see vkc.external.VKCCategoryDAO#getSubCategoryIdsRecursiv()
	 */
	public Set getSubCategoryIdsRecursiv() throws DBException {
		return internalCategoryDAO.getSubCategoryIdsRecursiv();
	}

	/**
	 * Speichert das aktuelle Projektunterordner
	 * 
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#save(javax.servlet.http.HttpSession)
	 */
	public void save(HttpSession session) throws VKCExternalException {
		internalCategoryDAO.save(session);
	}

	/**
	 * Speichert das aktuelle Projektunterordner
	 * 
	 * @param user
	 *            Der aktuelle Benutzer
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#save(vkc.external.VKCUserDAO)
	 */
	public void save(VKCUserDAO user) throws VKCExternalException {
		internalCategoryDAO.save(user);
	}

	/**
	 * Ändert den Wert des angegebenen dynamischen Attributes in diesem
	 * Projektunterordner
	 * 
	 * @param name
	 *            Zu änderndes Attribute
	 * @param newValue
	 *            Der neue Wert
	 * @param session
	 *            Session-Objekt in dem der aktuelle Benutzer hinterlegt ist
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#setDynaAttribute(java.lang.String,
	 *      java.lang.String, javax.servlet.http.HttpSession)
	 */
	public void setDynaAttribute(String name, String newValue,
			HttpSession session) throws VKCExternalException {
		internalCategoryDAO.setDynaAttribute(name, newValue, session);
	}

	/**
	 * Ändert den Wert des angegebenen dynamischen Attributes in diesem
	 * Projektunterordner
	 * 
	 * @param name
	 *            Zu änderndes Attribute
	 * @param newValue
	 *            Der neue Wert
	 * @param user
	 *            Der aktuelle Benutzer
	 * @throws VKCExternalException 
	 * @see vkc.external.VKCCategoryDAO#setDynaAttribute(java.lang.String,
	 *      java.lang.String, vkc.external.VKCUserDAO)
	 */
	public void setDynaAttribute(String name, String newValue, VKCUserDAO user) throws VKCExternalException {
		internalCategoryDAO.setDynaAttribute(name, newValue, user);
	}
}
