/*
 * $Id: DisplayAclForm.java,v 1.16 2005/09/15 13:43:58 marbobo Exp $
 * 
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * $Log: DisplayAclForm.java,v $
 * Revision 1.16  2005/09/15 13:43:58  marbobo
 * + Sprachabhängige Sortierung implementiert
 *
 * Revision 1.15  2004/11/30 09:58:26  jonyp
 * added support for ldapGroups
 *
 * Revision 1.14  2004/11/10 15:02:47  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.13  2004/07/20 15:19:57  jonyp
 * added some functionality to display dialog in mainframe or popup-window
 *
 * Revision 1.12  2004/04/27 15:10:36  jonyp
 * added few lines of code to add new permissions (a/q)
 *
 * Revision 1.11  2004/03/24 10:35:30  bigmac
 * Anzeige des Kategoriepfad durch Kategorienamen ersetzt
 *
 * Revision 1.10  2004/03/15 10:33:59  bigmac
 * Anpassungen an VKCPermissionSerializer und VKCAclTypeSerializer
 *
 * Revision 1.9  2004/03/13 20:46:14  bigmac
 * Weitere Refactorings ...
 *
 * Revision 1.8  2004/03/11 20:17:17  bigmac
 * Anpassungen an VKCUserSerializer
 *
 * Revision 1.7  2004/03/08 18:23:52  bigmac
 * Anpassungen an VKCLanguageSerializer und VKCLanguagePackSerializer
 *
 * Revision 1.6  2004/03/07 16:53:22  bigmac
 * Anpassungen an VKCAclSerializer
 *
 * Revision 1.5  2004/03/02 23:06:31  bigmac
 * Anpassungen an VKCDocumentSerializer und VKCCategorySerializer
 *
 * Revision 1.4  2004/02/24 13:32:26  vchris
 * Bugfix
 *
 * Revision 1.3  2004/02/23 16:18:55  vchris
 * DisplayACL Manager fertiggestellt
 *
 * Revision 1.2  2004/02/20 16:29:35  bigmac
 * Überflüssiges imports entfernt
 *
 * Revision 1.1  2004/02/17 17:06:12  vchris
 * Initiale Version
 *
 * 
 * Created on 16.02.2004
 */
package vkc.view.form;

import java.text.CollationKey;
import java.text.Collator;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.util.MessageResources;

import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCAclEntry;
import vkc.db.entities.VKCAclType;
import vkc.db.entities.VKCPermission;
import vkc.db.serializer.VKCAclSerializer;
import vkc.db.serializer.VKCCategorySerializer;
import vkc.db.serializer.VKCGroupSerializer;
import vkc.db.serializer.VKCPermissionSerializer;
import vkc.db.serializer.VKCUserSerializer;
import vkc.exception.DBException;
import vkc.ldap.db.entities.VKCLdapGroup;
import vkc.ldap.db.entities.VKCLdapServer;
import vkc.ldap.db.serializer.VKCLdapGroupSerializer;
import vkc.ldap.db.serializer.VKCLdapServerSerializer;
import vkc.misc.VKCLogManager;
import vkc.security.AccessorInfo;
import vkc.security.VKCAcl;
import vkc.util.VKCStringUtils;
import vkc.view.bean.GroupInfo;
import vkc.view.bean.UserInfo;
import vkc.view.PageId;

/**
 * DOCUMENT ME!!!
 * 
 * @author vchris
 */
public class DisplayAclForm extends ActionForm {

	public static final int ACTION_INIT				= 0;
	public static final int ACTION_CHANGE_SELECT 	= 1;
	public static final int ACTION_CLOSE			= 2;
	private static final String permissionsContext 	= "category";
	
	private VKCAcl acl					= null;
	private Map permissions;
	private String categoryPath			= "";
	private boolean defaultAcl			= false;

	private ArrayList users 			= new ArrayList();
	private ArrayList groups 			= new ArrayList();
	private ArrayList anyothers 		= new ArrayList();
	private ArrayList ldapGroups 		= new ArrayList();

	private String accessorSelect;
	private int ctrlAction				= ACTION_INIT; 
	private Integer categoryId			= null;
	private String ownWindow            = "true";

	private boolean changeAcl;				// c
	private boolean readCategory;			// r
	private boolean writeCategory;			// w
	private boolean deleteDocuments;		// d
	private boolean deleteCategory;			// D
	private boolean createSubcategory;		// C
	private boolean createLinkToCategory; 	// L
	private boolean followLinkToCategory;	// F
	private boolean followLinkToDocument;	// f
	private boolean createLinkToDocument;	// l
	private boolean archiveCategory;	    // a
	private boolean editQueryVirtualDocs;	// q
	
	private boolean changeAclEnabled;
	private boolean readCategoryEnabled;
	private boolean writeCategoryEnabled;
	private boolean deleteDocumentsEnabled;
	private boolean deleteCategoryEnabled;
	private boolean createSubcategoryEnabled;
	private boolean createLinkToCategoryEnabled;
	private boolean followLinkToCategoryEnabled;
	private boolean followLinkToDocumentEnabled;
	private boolean createLinkToDocumentEnabled;
	private boolean archiveCategoryEnabled;	    
	private boolean editQueryVirtualDocsEnabled;	

	protected Integer sourcePageId = PageId.CATEGORY_VIEW;
	protected Integer targetId = null;
	protected Integer subTargetId = null;


	// -- Vererbte Methoden -------------------------------------------------------------
	
	// -- Eigene Methoden ---------------------------------------------------------------
	
	/**
	 * Lädt die ACL aus der Datenbank
	 * 
	 * @param categoryId
	 * @param defaultAcl
	 * @return
	 */
	public void loadAcl(HttpServletRequest request, Integer categoryId, boolean defaultAcl) {
		
		// VKCAcl acl = new VKCAcl();
		
		if (categoryId == null) {
			VKCLogManager.errorLog(this,"","DisplayAcl: Missing parameter 'categoryId'");
			return ;
		} 
		
		try {

			VKCCategory category = VKCCategorySerializer.retrieveCategory(categoryId);
			categoryPath = category.getName();
			this.defaultAcl = defaultAcl;
			
			if (!defaultAcl) {
				acl = VKCAclSerializer.getAclByCategoryId(categoryId);
			} else {
				acl = VKCAclSerializer.getDefaultCatAcl(null, category, true);
			}
		}
		catch (Exception ex) {
			VKCLogManager.errorLog(this,"","DisplayAcl: Error retrieving ACL from database",ex);
			return;
		}

	
		// Verschiedene Objekte für methodenweite Verwendung holen
		MessageResources mRes 	= (MessageResources)(request.getAttribute(Globals.MESSAGES_KEY));
		Locale locale 			= (Locale)(request.getSession().getAttribute(Globals.LOCALE_KEY));
		
		// Benutzer, Gruppen, und Others in drei ArrayListen mit AccessorInfo Objekten extrahieren
		users.clear();
		groups.clear();				
		anyothers.clear();
		ldapGroups.clear();
		Collection aclEntries = acl.getAclEntries();
		for (Iterator it = aclEntries.iterator(); it.hasNext(); ) {
			VKCAclEntry c = (VKCAclEntry)it.next();
			if (c.getAclType().getAclTypeId().intValue() == VKCAclType.ANYOTHER_TYPE) {
				AccessorInfo ai = new AccessorInfo(
					mRes.getMessage(locale,"vkc.anyother"),
					new Integer(VKCAclType.ANYOTHER_TYPE), 
					c.getAccessorId());
				if (!anyothers.contains(ai)) anyothers.add(ai);
			}
			else if (c.getAclType().getAclTypeId().intValue() == VKCAclType.OWNER_TYPE) {
				AccessorInfo ai = new AccessorInfo(
					mRes.getMessage(locale,"vkc.owner"),
					new Integer(VKCAclType.OWNER_TYPE),
					c.getAccessorId());
				if (!anyothers.contains(ai)) anyothers.add(ai);
			}
			else if (c.getAclType().getAclTypeId().intValue() == VKCAclType.USER_TYPE) {
				try {
					UserInfo userinfo = VKCUserSerializer.retrieveUserInfo(c.getAccessorId());
					AccessorInfo ai = new AccessorInfo(userinfo.getLastnameLabel(), new Integer (VKCAclType.USER_TYPE), c.getAccessorId());
					if (!users.contains(ai)) users.add(ai);
				}
				catch (DBException e) {
					VKCLogManager.errorLog(this,"","DisplayAcl: Error retrieving userinfo",e);
				}
			}
			else if (c.getAclType().getAclTypeId().intValue() == VKCAclType.GROUP_TYPE) {
				try {
					GroupInfo groupinfo = VKCGroupSerializer.retrieveGroupInfo(c.getAccessorId());
					AccessorInfo ai = new AccessorInfo(groupinfo.getName(), new Integer(VKCAclType.GROUP_TYPE), c.getAccessorId());
					if (!groups.contains(ai)) groups.add(ai);
				}
				catch(DBException e) {
					VKCLogManager.errorLog(this,"","DisplayAcl: Error retrieving groupinfo",e);					
				}
			}
			else if (c.getAclType().getAclTypeId().intValue() == VKCAclType.LDAP_GROUP_TYPE) {
				try {
					VKCLdapGroup ldapGroup = VKCLdapGroupSerializer.retrieveLdapGroup(c.getAccessorId());
					VKCLdapServer ldapServer = VKCLdapServerSerializer.retrieveLdapServer(ldapGroup.getLdapServerId());
					
					AccessorInfo ai = new AccessorInfo(ldapServer.getDescription() + ": " + ldapGroup.getLdapGroupRDN(), new Integer(VKCAclType.LDAP_GROUP_TYPE), c.getAccessorId());
					if (!ldapGroups.contains(ai)) ldapGroups.add(ai);
				}
				catch(DBException e) {
					VKCLogManager.errorLog(this,"","DisplayAcl: Error retrieving groupinfo",e);					
				}
			}
		}

		final Collator collator = Collator.getInstance(locale);

		// sortieren
		Comparator accessorComparator = new Comparator () {
		  public int compare (Object o1, Object o2) {
			AccessorInfo u1 = (AccessorInfo)o1;
			AccessorInfo u2 = (AccessorInfo)o2;
			
        	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u1.getAccessorName()));
        	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u2.getAccessorName()));
        	
        	return key1.compareTo(key2);
		  }
		};

		AccessorInfo[] aiUsers = (AccessorInfo[])users.toArray(new AccessorInfo[0]);
		Arrays.sort(aiUsers, accessorComparator);
		List uList = Arrays.asList(aiUsers);
		users.clear();
		users = new ArrayList(uList);

		AccessorInfo[] aiGroups = (AccessorInfo[])groups.toArray(new AccessorInfo[0]);
		Arrays.sort(aiGroups, accessorComparator);
		List gList = Arrays.asList(aiGroups);
		groups.clear();
		groups = new ArrayList(gList);

	}
	
	/**
	 * Setzt alle 'enabled'-Bits in der Form für die entsprechenden Permissions
	 * 
	 * @param request
	 */
	public void initPermissions(HttpServletRequest request) {
		try {
			permissions = VKCPermissionSerializer.getPermissions(permissionsContext);
			
			if (permissions.get("c") == null) {
            	changeAclEnabled = false;
			} else {
				changeAclEnabled = ((VKCPermission)(permissions.get("c"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("r") == null) {
				readCategoryEnabled = false;
			} else {
				readCategoryEnabled = ((VKCPermission)(permissions.get("r"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("w") == null) {
				writeCategoryEnabled = false;
			} else {
				writeCategoryEnabled = ((VKCPermission)(permissions.get("w"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("d") == null) {
				deleteDocumentsEnabled = false;
			} else {
				deleteDocumentsEnabled = ((VKCPermission)(permissions.get("d"))).getEnabled().intValue() != 0;
			}
					
			if (permissions.get("a") == null) {
				archiveCategoryEnabled = false;
			} else {
				archiveCategoryEnabled = ((VKCPermission)(permissions.get("a"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("q") == null) {
				editQueryVirtualDocsEnabled = false;
			} else {
				editQueryVirtualDocsEnabled = ((VKCPermission)(permissions.get("q"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("D") == null) {
				deleteCategoryEnabled = false;
			} else {
				deleteCategoryEnabled = ((VKCPermission)(permissions.get("D"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("C") == null) {
				createSubcategoryEnabled = false;
			} else {
				createSubcategoryEnabled = ((VKCPermission)(permissions.get("C"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("L") == null) {
				createLinkToCategoryEnabled = false;
			} else {
				createLinkToCategoryEnabled = ((VKCPermission)(permissions.get("L"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("F") == null) {
				followLinkToCategoryEnabled = false;
			} else {
				followLinkToCategoryEnabled = ((VKCPermission)(permissions.get("F"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("l") == null) {
				createLinkToDocumentEnabled = false;
			} else {
				createLinkToDocumentEnabled = ((VKCPermission)(permissions.get("l"))).getEnabled().intValue() != 0;
			}
			
			if (permissions.get("f") == null) {
				followLinkToDocumentEnabled = false;
			} else {
				followLinkToDocumentEnabled = ((VKCPermission)(permissions.get("f"))).getEnabled().intValue() != 0;	
			}		
		} catch(Exception ex) {
			VKCLogManager.errorLog(this,"","Error retrieving permissions from Database",ex);
		}
		
	}

	/**
	 * Setzt den Wert einer Checkbox anhand des übergebenen VKCAclEntry Objektes
	 * 
	 * @param c
	 */
	public void setCheckboxValue(VKCAclEntry c) {
		// neue Berechtig setzen
		char token = c.getPermission().getToken();
		if (token == 'c') setChangeAcl(true);
		if (token == 'r') setReadCategory(true);
		if (token == 'w') setWriteCategory(true);
		if (token == 'd') setDeleteDocuments(true);
		if (token == 'D') setDeleteCategory(true);
		if (token == 'C') setCreateSubcategory(true);
		if (token == 'L') setCreateLinkToCategory(true);
		if (token == 'F') setFollowLinkToCategory(true);
		if (token == 'l') setCreateLinkToDocument(true);
		if (token == 'f') setFollowLinkToDocument(true);
	}

	/**
	 * Setzt alle Checkboxen auf einen den übergebenen boolean-Wert
	 * 
	 * @param value
	 */
	public void setAllCheckboxesToValue(boolean value) {
		setChangeAcl(value);
		setReadCategory(value);
		setWriteCategory(value);
		setDeleteDocuments(value);
		setDeleteCategory(value);
		setCreateSubcategory(value);
		setCreateLinkToCategory(value);
		setFollowLinkToCategory(value);
		setCreateLinkToDocument(value);
		setFollowLinkToDocument(value);		
	}
	
	// -- Getter/Setter Methoden --------------------------------------------------------

	/**
	 * @return
	 */
	public String getAccessorSelect() {
		return accessorSelect;
	}

	public VKCAcl getAcl() {
		return acl;
	}

	public ArrayList getAnyothers() {
		return anyothers;
	}

	public Integer getCategoryId() {
		return categoryId;
	}

	public int getCtrlAction() {
		return ctrlAction;
	}

	public ArrayList getGroups() {
		return groups;
	}

	public ArrayList getLdapGroups() {
		return ldapGroups;
	}
	
	public ArrayList getUsers() {
		return users;
	}

	public void setAccessorSelect(String string) {
		accessorSelect = string;
	}

	public void setAcl(VKCAcl acl) {
		this.acl = acl;
	}

	public void setAnyothers(ArrayList list) {
		anyothers = list;
	}

	public void setCategoryId(Integer integer) {
		categoryId = integer;
	}

	public void setCtrlAction(int i) {
		ctrlAction = i;
	}

	public void setGroups(ArrayList list) {
		groups = list;
	}

	public void setLdapGroups(ArrayList list) {
		ldapGroups = list;
	}
	
	public void setUsers(ArrayList list) {
		users = list;
	}

	public boolean isChangeAcl() {
		return changeAcl;
	}

	public boolean isChangeAclEnabled() {
		return changeAclEnabled;
	}

	public boolean isCreateLinkToCategory() {
		return createLinkToCategory;
	}

	public boolean isCreateLinkToCategoryEnabled() {
		return createLinkToCategoryEnabled;
	}

	public boolean isCreateLinkToDocument() {
		return createLinkToDocument;
	}

	public boolean isCreateLinkToDocumentEnabled() {
		return createLinkToDocumentEnabled;
	}

	public boolean isCreateSubcategory() {
		return createSubcategory;
	}

	public boolean isCreateSubcategoryEnabled() {
		return createSubcategoryEnabled;
	}

	public boolean isDeleteCategory() {
		return deleteCategory;
	}

	public boolean isDeleteCategoryEnabled() {
		return deleteCategoryEnabled;
	}

	public boolean isDeleteDocuments() {
		return deleteDocuments;
	}

	public boolean isDeleteDocumentsEnabled() {
		return deleteDocumentsEnabled;
	}

	public boolean isFollowLinkToCategory() {
		return followLinkToCategory;
	}

	public boolean isFollowLinkToCategoryEnabled() {
		return followLinkToCategoryEnabled;
	}

	public boolean isFollowLinkToDocument() {
		return followLinkToDocument;
	}

	public boolean isFollowLinkToDocumentEnabled() {
		return followLinkToDocumentEnabled;
	}

	public Map getPermissions() {
		return permissions;
	}

	public boolean isReadCategory() {
		return readCategory;
	}

	public boolean isReadCategoryEnabled() {
		return readCategoryEnabled;
	}

	public boolean isWriteCategory() {
		return writeCategory;
	}

	public boolean isWriteCategoryEnabled() {
		return writeCategoryEnabled;
	}

	public void setChangeAcl(boolean b) {
		changeAcl = b;
	}

	public void setChangeAclEnabled(boolean b) {
		changeAclEnabled = b;
	}

	public void setCreateLinkToCategory(boolean b) {
		createLinkToCategory = b;
	}

	public void setCreateLinkToCategoryEnabled(boolean b) {
		createLinkToCategoryEnabled = b;
	}

	public void setCreateLinkToDocument(boolean b) {
		createLinkToDocument = b;
	}

	public void setCreateLinkToDocumentEnabled(boolean b) {
		createLinkToDocumentEnabled = b;
	}

	public void setCreateSubcategory(boolean b) {
		createSubcategory = b;
	}

	public void setCreateSubcategoryEnabled(boolean b) {
		createSubcategoryEnabled = b;
	}

	public void setDeleteCategory(boolean b) {
		deleteCategory = b;
	}

	public void setDeleteCategoryEnabled(boolean b) {
		deleteCategoryEnabled = b;
	}

	public void setDeleteDocuments(boolean b) {
		deleteDocuments = b;
	}

	public void setDeleteDocumentsEnabled(boolean b) {
		deleteDocumentsEnabled = b;
	}

	public void setFollowLinkToCategory(boolean b) {
		followLinkToCategory = b;
	}

	public void setFollowLinkToCategoryEnabled(boolean b) {
		followLinkToCategoryEnabled = b;
	}

	public void setFollowLinkToDocument(boolean b) {
		followLinkToDocument = b;
	}

	public void setFollowLinkToDocumentEnabled(boolean b) {
		followLinkToDocumentEnabled = b;
	}

	public void setPermissions(Map map) {
		permissions = map;
	}

	public void setReadCategory(boolean b) {
		readCategory = b;
	}

	public void setReadCategoryEnabled(boolean b) {
		readCategoryEnabled = b;
	}

	public void setWriteCategory(boolean b) {
		writeCategory = b;
	}

	public void setWriteCategoryEnabled(boolean b) {
		writeCategoryEnabled = b;
	}

	public String getCategoryPath() {
		return categoryPath;
	}

	public boolean isDefaultAcl() {
		return defaultAcl;
	}

	public void setDefaultAcl(boolean b) {
		defaultAcl = b;
	}

	public boolean isArchiveCategory() {
		return archiveCategory;
	}

	public boolean isArchiveCategoryEnabled() {
		return archiveCategoryEnabled;
	}

	public boolean isEditQueryVirtualDocs() {
		return editQueryVirtualDocs;
	}

	public boolean isEditQueryVirtualDocsEnabled() {
		return editQueryVirtualDocsEnabled;
	}

	public void setArchiveCategory(boolean b) {
		archiveCategory = b;
	}

	public void setArchiveCategoryEnabled(boolean b) {
		archiveCategoryEnabled = b;
	}

	public void setEditQueryVirtualDocs(boolean b) {
		editQueryVirtualDocs = b;
	}

	public void setEditQueryVirtualDocsEnabled(boolean b) {
		editQueryVirtualDocsEnabled = b;
	}

	public String getOwnWindow() {
		return ownWindow;
	}

	public void setOwnWindow(String string) {
		ownWindow = string;
	}

	public Integer getSourcePageId() {
		return sourcePageId;
	}

	public void setSourcePageId(Integer integer) {
		sourcePageId = integer;
	}

	public Integer getTargetId() {
		return targetId;
	}

	public void setTargetId(Integer integer) {
		targetId = integer;
	}

	public Integer getSubTargetId() {
		return subTargetId;
	}

	public void setSubTargetId(Integer integer) {
		subTargetId = integer;
	}

}