package edu.teco.dnd.module;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.UUID;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import edu.teco.dnd.blocks.FunctionBlock;
import edu.teco.dnd.blocks.Input;
import edu.teco.dnd.blocks.Output;

public class FunctionBlockSecurityDecorator {
	private static final Logger LOGGER = LogManager.getLogger(FunctionBlockSecurityDecorator.class);

	private final FunctionBlock block;

	public FunctionBlockSecurityDecorator(final FunctionBlock block) {
		this.block = block;
	}

	public static FunctionBlockSecurityDecorator getDecorator(final Class<? extends FunctionBlock> blockClass) {
		final FunctionBlock realBlock;
		try {
			realBlock = (FunctionBlock) blockClass.getConstructor().newInstance();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			return null;
		} catch (SecurityException e) {
			e.printStackTrace();
			return null;
		} catch (InstantiationException e) {
			e.printStackTrace();
			return null;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			return null;
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			return null;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			return null;
		}
		return new FunctionBlockSecurityDecorator(realBlock);
	}

	public boolean doInit(final UUID blockUUID) {
		try {
			this.block.doInit(blockUUID);
		} catch (IllegalAccessException e) {
			Thread.dumpStack();
			LOGGER.warn("{} threw an exception in doInit()", block);
			return LOGGER.exit(false);
		}
		return true;
	}

	public boolean init() {
		try {
			block.init();
		} catch (Throwable t) {
			Thread.dumpStack();
			LOGGER.warn("{} threw an exception in init()", block);
			return LOGGER.exit(false);
		}
		return true;
	}

	public boolean shutdown() {
		try {
			block.shutdown();
		} catch (Throwable t) {
			Thread.dumpStack();
			LOGGER.warn("{} threw an exception in init()", block);
			return LOGGER.exit(false);
		}
		return true;
	}

	public boolean update() {
		try {
			block.update();
		} catch (Throwable t) {
			Thread.dumpStack();
			return LOGGER.exit(false);
		}
		return true;
	}

	public FunctionBlock getRealBlock() {
		return block;
	}

	/**
	 * 
	 * @return type of the block this FunctionBlockSecurityDecorator contains.
	 */
	public String getBlockType() {
		return block.getBlockType();
	}

	/**
	 * 
	 * @return UUID of the block this FunctionBlockSecurityDecorator contains.
	 */
	public UUID getBlockUUID() {
		return block.getBlockUUID();
	}

	/**
	 * 
	 * @return updateIntervall of the block this FunctionBlockSecurityDecorator contains.
	 * @see FunctionBlock.getUpdateIntervall()
	 */
	public long getUpdateInterval() {

		return block.getUpdateInterval();
	}

	/**
	 * 
	 * @return Outputs of the block this FunctionBlockSecurityDecorator contains.
	 * @see FunctionBlock.getOutputs()
	 */
	public Map<String, Output<? extends Serializable>> getOutputs() {
		return block.getOutputs();
	}

	/**
	 * 
	 * @return inputs of the block this FunctionBlockSecurityDecorator contains.
	 * @see FunctionBlock.getInputs()
	 */
	public Map<String, Input<? extends Serializable>> getInputs() {
		return block.getInputs();
	}

}

@@ -56,60 +56,8 @@
 le;%0A
-import java.lang.reflect.InvocationTargetException;%0A
 impo
@@ -181,16 +181,108 @@
 .Logger;
+%0Aimport org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
 %0A%0Aimport
@@ -903,451 +903,111 @@
 ch (
-IllegalArgumentException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%09return null;%0A%09%09%7D catch (SecurityException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%09return null;%0A%09%09%7D catch (InstantiationException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%09return null;%0A%09%09%7D catch (IllegalAccessException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%09return null;%0A%09%09%7D catch (InvocationTargetException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%09return null;%0A%09%09%7D catch (NoSuchMethodException e) %7B%0A%09%09%09e.printStackTrace(
+Throwable e) %7B%0A%09%09%09Thread.dumpStack();%0A%09%09%09LOGGER.warn(%22%7B%7D threw an exception in constructor%22, blockClass
 );%0A%09
@@ -1208,24 +1208,88 @@
 eption e) %7B%0A
+%09%09%09// do not access anything on e outside of another try/catch!%0A
 %09%09%09Thread.du
@@ -1388,38 +1388,194 @@
 (false);%0A%09%09%7D
-%0A%09%09return 
+ catch (Throwable e) %7B%0A%09%09%09// do not access anything on e outside of another try/catch!%0A%09%09%09Thread.dumpStack();%0A%09%09%09return LOGGER.exit(false);%0A%09%09%7D%0A%09%09return LOGGER.exit(
 true
+)
 ;%0A%09%7D%0A%0A%09publi
@@ -1918,36 +1918,40 @@
 an exception in 
-init
+shutdown
 ()%22, block);%0A%09%09%09
@@ -2148,32 +2148,117 @@
 eturn true;%0A%09%7D%0A%0A
+%09/**%0A%09 * Dangerous. Use with extreme care.%0A%09 * %0A%09 * @return the insecure block.%0A%09 */%0A
 %09public Function

Secure a possible break out of secured code in constructor.