/*
 * Copyright 2009-2010 The MICE Project Team.
 * Licensed under the MICE s.r.l.
 * End User License Agreement
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.micegroup.it/voila/license.html
 */
package it.mice.voila.runtime.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

/**
 * Post processor di spring che post-elabora il bean FilterInvocationSecurityMetadataSource caricondo in esso
 * tutti i security config parameters leggendoli dalla tabella Security Elementary Operation.
 */
public class InMemoryFilterSecurityInterceptorPostProcessor extends AbstractFilterSecurityInterceptorPostProcessor {
	/**
	 * Default logger.
	 */
	private static final Log LOGGER = LogFactory.getLog(InMemoryFilterSecurityInterceptorPostProcessor.class);

	private Collection<OperationConfigAttribute> elementaryOperationList = new ArrayList<OperationConfigAttribute>();

	/**
	 * Getter per la proprietà elementaryOperationList.
	 * @return la proprietà elementaryOperationList
	 */
	public Collection<OperationConfigAttribute> getElementaryOperationList() {
		return elementaryOperationList;
	}

	/**
	 * Setter per la proprietà elementaryOperationList.
	 * @param elementaryOperationList la proprietà elementaryOperationList da settare
	 */
	public void setElementaryOperationList(Collection<OperationConfigAttribute> elementaryOperationList) {
		this.elementaryOperationList = elementaryOperationList;
	}

	/**
	 * Il metodo popola la requestMap con tutte le elementary operation links definiti nella tabella Security
	 * Elementary Operation.
	 * 
	 * @param requestMap request map object da popolare
	 * 
	 */
	protected void populateRequestMapFromSiteMap(
			Map<RequestMatcher, Collection<ConfigAttribute>> requestMap) {
		if (elementaryOperationList.size() == 0) {
			LOGGER.warn("Current application "
					+ " has no elementary operation or its ID is wrong. Check applicationContext-Security.xml file.");
		}
		Iterator<OperationConfigAttribute> iOper = elementaryOperationList.iterator();
		int c = 1;
		while (iOper.hasNext()) {
			OperationConfigAttribute theElementaryOperation = iOper.next();
			if (theElementaryOperation.getOperationId() == 0) {
				theElementaryOperation.setOperationId(c++);
			}
			String methodName = theElementaryOperation.getOperationName();
			List<ConfigAttribute> cad = buildConfigAttributeDefinition(theElementaryOperation);
			try {
				requestMap.put(new AntPathRequestMatcher(methodName + "*"), cad);
			} catch (IllegalArgumentException e) {
				LOGGER.error("Problem during method definition map building from table SecurityElementaryOperation. Check data table for "
						+ methodName + ". Cause:" + e.getMessage());
			}
		}
	}

	/**
	 * Riceve in input una elementary operation e restituisce la spring security configuration attribute list
	 * corrispondente.
	 * 
	 * @param theElementaryOperation l'elementary operation da elaborare.
	 * @return la spring security configuration attribute list corrispondente.
	 */
	private List<ConfigAttribute> buildConfigAttributeDefinition(
			OperationConfigAttribute theElementaryOperation) {
		List<ConfigAttribute> cad = new ArrayList<ConfigAttribute>();
		// Add complex ConfigAttribute for run-time execution check.
		cad.add(theElementaryOperation);
		return cad;
	}
	// Estendi questo oggetto dopo questo commento in modo da limitare conflitti durante la sincronizzazione
	// di nuove generazioni.
}
