/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.slee.container.management.jmx.editors;

import javax.slee.ComponentID;

/**
 *Property editor for component ID array.
 *
 */
public class ComponentIDArrayPropertyEditor
		extends TextPropertyEditorSupport {

	public final String CID_SEPARATOR = ";";

    public String getAsText( ) {
        ComponentID[] componentIds = (ComponentID[]) this.getValue();
        if ( componentIds == null) return "null";
        else {
            StringBuffer sb = new StringBuffer();
            for ( int i = 0; i < componentIds.length; i++) {
                sb.append(componentIds[i].toString());
                if (i < componentIds.length-1) {
                	sb.append(CID_SEPARATOR);
                }
            }
            return sb.toString();
        }
    }

    /**
     * Set the element as text value, parse it and setValue.
     * The separator is CID_SEPARATOR
     */
    public void setAsText(String text ) {
        if ( text == null || text.equals("")) {
            super.setValue( new ComponentID[0]);
        } else {
            java.util.ArrayList results = new java.util.ArrayList();
            // the format for component ID is name vendor version.
            java.util.StringTokenizer st = new java.util.StringTokenizer(text,CID_SEPARATOR,true);
            ComponentIDPropertyEditor cidPropEditor = new ComponentIDPropertyEditor();
            while (st.hasMoreTokens()) {
                cidPropEditor.setAsText(st.nextToken());
                if (st.hasMoreTokens()) {
                	st.nextToken();
                }
                results.add(cidPropEditor.getValue());
            }
            ComponentID[] cid = new ComponentID[results.size()];
            results.toArray(cid);
            this.setValue(cid);
        }

    }

}


/*
 * TeleStax, Open Source Cloud Communications
 * Copyright 2011-2014, Telestax Inc and individual contributors
 * by the @authors tag.
 *
 * This program is free software: you can redistribute it and/or modify
 * under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 * This file incorporates work covered by the following copyright contributed under the GNU LGPL : Copyright 2007-2011 Red Hat.
 */
package org.mobicents.slee.runtime.eventrouter;

import org.mobicents.slee.container.SleeContainer;
import org.mobicents.slee.container.activity.ActivityContextHandle;
import org.mobicents.slee.container.event.EventContext;
import org.mobicents.slee.container.eventrouter.EventRouterExecutor;
import org.mobicents.slee.container.eventrouter.EventRoutingTask;
import org.mobicents.slee.container.eventrouter.stats.EventRouterExecutorStatistics;
import org.mobicents.slee.runtime.eventrouter.routingtask.EventRoutingTaskImpl;
import org.mobicents.slee.runtime.eventrouter.stats.EventRouterExecutorStatisticsImpl;

import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author martins
 *
 */
public class EventRouterExecutorImpl implements EventRouterExecutor {

	private final ExecutorService executor;
	private final EventRouterExecutorStatisticsImpl stats;
	private final SleeContainer sleeContainer;

	/**
	 * Used to collect executing stats of an {@link EventRoutingTask}.
	 *
	 * @author martins
	 *
	 */
	private class EventRoutingTaskStatsCollector implements Runnable {

		private final EventRoutingTask eventRoutingTask;

		public EventRoutingTaskStatsCollector(EventRoutingTask eventRoutingTask) {
			this.eventRoutingTask = eventRoutingTask;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
			final long startTime = System.nanoTime();
			eventRoutingTask.run();
			stats.eventRouted(eventRoutingTask.getEventContext().getEventTypeId(), System
					.nanoTime()
					- startTime);
		}
	}

	/**
	 * Used to collect executing stats of a misc {@link Runnable} task.
	 *
	 * @author martins
	 *
	 */
	private class MiscTaskStatsCollector implements Runnable {

		private final Runnable runnable;

		public MiscTaskStatsCollector(Runnable runnable) {
			this.runnable = runnable;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
			final long startTime = System.nanoTime();
			runnable.run();
			stats.miscTaskExecuted(System.nanoTime() - startTime);
		}
	}

	/**
	 *
	 */
	public EventRouterExecutorImpl(boolean collectStats, ThreadFactory threadFactory, SleeContainer sleeContainer) {
		final LinkedBlockingQueue<Runnable> executorQueue = new LinkedBlockingQueue<Runnable>();
		this.executor = new ThreadPoolExecutor(1, 1,
                        0L, TimeUnit.MILLISECONDS,
                        executorQueue, threadFactory);
		stats = collectStats ? new EventRouterExecutorStatisticsImpl(Collections.unmodifiableCollection(executorQueue)) : null;
		this.sleeContainer = sleeContainer;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#getStatistics
	 * ()
	 */
	public EventRouterExecutorStatistics getStatistics() {
		return stats;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#shutdown()
	 */
	public void shutdown() {
		executor.shutdown();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#execute(java
	 * .lang.Runnable)
	 */
	public void execute(Runnable task) {
		if (stats == null) {
			executor.execute(task);
		} else {
			executor.execute(new MiscTaskStatsCollector(task));
		}
	}

	/* (non-Javadoc)
	 * @see org.mobicents.slee.core.runtime.eventrouter.EventRouterExecutor#executeNow(java.lang.Runnable)
	 */
	public void executeNow(Runnable task) throws InterruptedException, ExecutionException {
		if (stats == null) {
			executor.submit(task).get();
		} else {
			executor.submit(new MiscTaskStatsCollector(task)).get();
		}
	}

	/* (non-Javadoc)
	 * @see org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#activityMapped(org.mobicents.slee.runtime.activity.ActivityContextHandle)
	 */
	public void activityMapped(ActivityContextHandle ach) {
		if (stats != null) {
			stats.activityMapped(ach);
		}
	}

	/* (non-Javadoc)
	 * @see org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#activityUnmapped(org.mobicents.slee.runtime.activity.ActivityContextHandle)
	 */
	public void activityUnmapped(ActivityContextHandle ach) {
		if (stats != null) {
			stats.activityUnmapped(ach);
		}
	}

	/* (non-Javadoc)
	 * @see org.mobicents.slee.runtime.eventrouter.EventRouterExecutor#routeEvent(org.mobicents.slee.core.event.SleeEvent)
	 */
	public void routeEvent(EventContext event) {
		final EventRoutingTaskImpl eventRoutingTask = new EventRoutingTaskImpl(event,sleeContainer);
		if (stats == null) {
			executor.execute(eventRoutingTask);
		} else {
			executor.execute(new EventRoutingTaskStatsCollector(
					eventRoutingTask));
		}
	}

}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.slee.container.management.jmx;

import java.util.Arrays;

import javax.management.ObjectName;
import javax.slee.InvalidArgumentException;
import javax.slee.InvalidStateException;
import javax.slee.SbbID;
import javax.slee.management.DependencyException;
import javax.slee.management.LinkNameAlreadyBoundException;
import javax.slee.management.ManagementException;
import javax.slee.management.ResourceAdaptorEntityAlreadyExistsException;
import javax.slee.management.ResourceAdaptorEntityState;
import javax.slee.management.UnrecognizedLinkNameException;
import javax.slee.management.UnrecognizedResourceAdaptorEntityException;
import javax.slee.management.UnrecognizedResourceAdaptorException;
import javax.slee.resource.ConfigProperties;
import javax.slee.resource.InvalidConfigurationException;
import javax.slee.resource.ResourceAdaptorID;

import org.apache.log4j.Logger;
import org.mobicents.slee.container.management.ResourceManagementImpl;

/**
 *
 * @author Stefano Zappaterra
 * @author Eduardo Martins
 *
 */
public class ResourceManagementMBeanImpl extends MobicentsServiceMBeanSupport implements
		ResourceManagementMBeanImplMBean {

	private final static Logger logger = Logger
			.getLogger(ResourceManagementMBeanImpl.class);

	private final ResourceManagementImpl resourceManagement;

	public ResourceManagementMBeanImpl(ResourceManagementImpl resourceManagement) {
		super(resourceManagement.getSleeContainer());
		this.resourceManagement = resourceManagement;
	}

	// ------- MANAGEMENT OPERATIONS

	public void createResourceAdaptorEntity(ResourceAdaptorID id,
			String entityName, ConfigProperties properties)
			throws NullPointerException, InvalidArgumentException,
			UnrecognizedResourceAdaptorException,
			ResourceAdaptorEntityAlreadyExistsException,
			InvalidConfigurationException, ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.createResourceAdaptorEntity(id, entityName, properties);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (InvalidArgumentException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorException e) {
			throw e;
		} catch (ResourceAdaptorEntityAlreadyExistsException e) {
			throw e;
		} catch (InvalidConfigurationException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to create RA entity with name " + entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void activateResourceAdaptorEntity(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, InvalidStateException,
			ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.activateResourceAdaptorEntity(entityName);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (InvalidStateException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to activate RA entity with name " + entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void deactivateResourceAdaptorEntity(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, InvalidStateException,
			ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.deactivateResourceAdaptorEntity(entityName);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (InvalidStateException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to deactivate RA entity with name " + entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void removeResourceAdaptorEntity(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, InvalidStateException,
			DependencyException, ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.removeResourceAdaptorEntity(entityName);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (InvalidStateException e) {
			throw e;
		} catch (DependencyException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to remove RA entity with name " + entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void updateConfigurationProperties(String entityName,
			ConfigProperties properties) throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, InvalidStateException,
			InvalidConfigurationException, ManagementException {
		try {
			resourceManagement.updateConfigurationProperties(entityName, properties);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (InvalidStateException e) {
			throw e;
		} catch (InvalidConfigurationException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to update configuration properties for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void bindLinkName(String entityName, String linkName)
			throws NullPointerException, InvalidArgumentException,
			UnrecognizedResourceAdaptorEntityException,
			LinkNameAlreadyBoundException, ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.bindLinkName(linkName,
						entityName);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (LinkNameAlreadyBoundException e) {
			throw e;
		} catch (InvalidArgumentException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to bind link name " + linkName
					+ " to RA entity with name " + entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public void unbindLinkName(String linkName) throws NullPointerException,
			UnrecognizedLinkNameException, DependencyException,
			ManagementException {
		try {
			synchronized (getSleeContainer().getManagementMonitor()) {
				resourceManagement.unbindLinkName(linkName);
			}
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedLinkNameException e) {
			throw e;
		} catch (DependencyException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to unbind link name " + linkName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getResourceAdaptorEntities(ResourceAdaptorEntityState state)
			throws NullPointerException, ManagementException {
		try {
			return resourceManagement.getResourceAdaptorEntities(state);
		} catch (NullPointerException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get RA entities with state " + state;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getLinkNames() throws ManagementException {
		try {
			return resourceManagement
					.getLinkNames();
		} catch (Throwable e) {
			String s = "failed to get link names";
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getLinkNames(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, ManagementException {
		try {
			return resourceManagement.getLinkNames(entityName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get link names for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public ConfigProperties getConfigurationProperties(ResourceAdaptorID raID)
			throws NullPointerException, UnrecognizedResourceAdaptorException,
			ManagementException {
		try {
			return resourceManagement.getConfigurationProperties(raID);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get configuration propertiess for RA with id "
					+ raID;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public ConfigProperties getConfigurationProperties(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, ManagementException {
		try {
			return resourceManagement.getConfigurationProperties(entityName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get configuration properties for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public ResourceAdaptorID getResourceAdaptor(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, ManagementException {
		try {
			return resourceManagement.getResourceAdaptor(entityName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get RA ID for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getResourceAdaptorEntities() throws ManagementException {
		try {
			return resourceManagement.getResourceAdaptorEntities();
		} catch (Throwable e) {
			String s = "failed to get RA entities";
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getResourceAdaptorEntities(ResourceAdaptorID id)
			throws NullPointerException, UnrecognizedResourceAdaptorException,
			ManagementException {
		try {
			return resourceManagement.getResourceAdaptorEntities(id);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get RA entities for RA with id " + id;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String[] getResourceAdaptorEntities(String[] linkNames)
			throws NullPointerException, ManagementException {
		try {
			return resourceManagement.getResourceAdaptorEntities(linkNames);
		} catch (NullPointerException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get RA entities for link names "
					+ Arrays.asList(linkNames);
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public String getResourceAdaptorEntity(String linkName)
			throws NullPointerException, UnrecognizedLinkNameException,
			ManagementException {
		try {
			return resourceManagement.getResourceAdaptorEntityName(linkName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedLinkNameException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get RA entities for link name " + linkName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public ResourceAdaptorEntityState getState(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException, ManagementException {
		try {
			return resourceManagement.getState(entityName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get state for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public SbbID[] getBoundSbbs(String linkName) throws NullPointerException,
			UnrecognizedLinkNameException, ManagementException {
		try {
			return resourceManagement.getBoundSbbs(linkName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedLinkNameException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get bound sbbs to link name "
					+ linkName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

	public ObjectName getResourceUsageMBean(String entityName)
			throws NullPointerException,
			UnrecognizedResourceAdaptorEntityException,
			InvalidArgumentException, ManagementException {
		try {
			return resourceManagement.getResourceUsageMBean(entityName);
		} catch (NullPointerException e) {
			throw e;
		} catch (UnrecognizedResourceAdaptorEntityException e) {
			throw e;
		} catch (InvalidArgumentException e) {
			throw e;
		} catch (Throwable e) {
			String s = "failed to get resource usage mbean for RA entity with name "
					+ entityName;
			logger.error(s, e);
			throw new ManagementException(s, e);
		}
	}

}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.slee.container.deployment;

import java.util.Iterator;
import java.util.Map;

import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;

import javax.slee.SLEEException;
import javax.slee.management.DeploymentException;

import org.apache.log4j.Logger;
import org.mobicents.slee.ActivityContextInterfaceExt;
import org.mobicents.slee.container.component.ClassPool;
import org.mobicents.slee.runtime.sbb.SbbActivityContextInterfaceImpl;

/**
 * Class generating the concrete activity context interface class from the
 * activity context interface provided by a sbb developer
 *
 * @author DERUELLE Jean <a
 *         href="mailto:jean.deruelle@gmail.com">jean.deruelle@gmail.com </a>
 * @author F.Moggia fixed activitycontext
 */
public class ConcreteActivityContextInterfaceGenerator {

	/**
	 * Logger to logg information
	 */
	private static Logger logger = null;

	/**
	 * Pool to generate or read classes with javassist
	 */
	private final ClassPool pool;

	/**
	 * The path where classes will reside
	 */
	private final String deployDir;

	/**
	 * the sbb activity context interface name
	 */
	private final String activityContextInterfaceName;

	/**
	 * The interface from which to generate the concrete interface
	 */
	protected CtClass activityContextInterface = null;

	/**
	 * The the concrete activity interface
	 */
	protected CtClass concreteActivityContextInterface = null;

	static {
		logger = Logger
				.getLogger(ConcreteActivityContextInterfaceGenerator.class);
	}

	/**
	 *
	 */
	public ConcreteActivityContextInterfaceGenerator(
			String activityContextInterfaceName, String deployDir,
			ClassPool classPool) {
		this.pool = classPool;
		this.deployDir = deployDir;
		this.activityContextInterfaceName = activityContextInterfaceName;
	}

	/**
	 * Generate the Activity Context Interface Class
	 *
	 * @param activityContextInterfaceName
	 *            the name of the Activity Context Interface
	 * @return the concrete Activity Context Interface class implementing the
	 *         Activity Context Interface
	 */
	public Class generateActivityContextInterfaceConcreteClass()
			throws DeploymentException {

		String tmpClassName = ConcreteClassGeneratorUtils.CONCRETE_ACTIVITY_INTERFACE_CLASS_NAME_PREFIX
				+ activityContextInterfaceName
				+ ConcreteClassGeneratorUtils.CONCRETE_ACTIVITY_INTERFACE_CLASS_NAME_SUFFIX;

		concreteActivityContextInterface = pool.makeClass(tmpClassName);
		CtClass sbbActivityContextInterface = null;
		try {
			activityContextInterface = pool.get(activityContextInterfaceName);
			sbbActivityContextInterface = pool
					.get(SbbActivityContextInterfaceImpl.class.getName());
		} catch (NotFoundException nfe) {
			throw new DeploymentException("Could not find aci "
					+ activityContextInterfaceName, nfe);
		}

		// Generates the extends link
		ConcreteClassGeneratorUtils.createInheritanceLink(
				concreteActivityContextInterface, sbbActivityContextInterface);

		// Generates the implements link
		ConcreteClassGeneratorUtils.createInterfaceLinks(
				concreteActivityContextInterface,
				new CtClass[] { activityContextInterface });

		// Generates the methods to implement from the interface
		Map interfaceMethods = ClassUtils
				.getInterfaceMethodsFromInterface(activityContextInterface);
		generateConcreteMethods(interfaceMethods);
		// generates the class
		String sbbDeploymentPathStr = deployDir;

		try {
			concreteActivityContextInterface.writeFile(sbbDeploymentPathStr);
			if (logger.isDebugEnabled()) {
				logger.debug("Concrete Class " + tmpClassName
						+ " generated in the following path "
						+ sbbDeploymentPathStr);
			}
		} catch (Exception e) {

			logger.error("problem generating concrete class", e);
			throw new DeploymentException(
					"problem generating concrete class! ", e);
		}

		// load the class
		Class clazz = null;
		try {
			clazz = Thread.currentThread().getContextClassLoader().loadClass(
					tmpClassName);
		} catch (Exception e1) {
			logger.error("problem loading generated class", e1);
			throw new DeploymentException(
					"problem loading the generated class! ", e1);
		}

		this.concreteActivityContextInterface.defrost();

		return clazz;

	}

	/**
	 * Generates the concrete methods of the class It generates a specific
	 * method implementation for the javax.slee.ActivityContextInterface methods
	 * for the methods coming from the ActivityContextInterface developer the
	 * call is routed to the base asbtract class
	 *
	 * @param interfaceMethods
	 *            the methods to implement coming from the
	 *            ActivityContextInterface developer
	 */
	private void generateConcreteMethods(Map interfaceMethods) {
		if (interfaceMethods == null)
			return;

		Iterator it = interfaceMethods.values().iterator();
		while (it.hasNext()) {
			CtMethod interfaceMethod = (CtMethod) it.next();
			if (interfaceMethod != null
					//&& isBaseInterfaceMethod(interfaceMethod.getName()))
					&& (interfaceMethod.getDeclaringClass().getName().equals(
							javax.slee.ActivityContextInterface.class.getName()) || interfaceMethod.getDeclaringClass().getName().equals(
									ActivityContextInterfaceExt.class.getName())))
				continue; // @todo: need to check args also

			try {
				// copy method from abstract to concrete class
				CtMethod concreteMethod = CtNewMethod.copy(interfaceMethod,
						concreteActivityContextInterface, null);
				// create the method body
				String fieldName = interfaceMethod.getName().substring(3);
				fieldName = fieldName.substring(0, 1).toLowerCase()
						+ fieldName.substring(1);
				String concreteMethodBody = null;
				if (interfaceMethod.getName().startsWith("get")) {
					concreteMethodBody = "{ return ($r)getFieldValue(\""
							+ fieldName + "\","+concreteMethod.getReturnType().getName()+".class); }";
				} else if (interfaceMethod.getName().startsWith("set")) {
					concreteMethodBody = "{ setFieldValue(\"" + fieldName
							+ "\",$1); }";
				} else {
					throw new SLEEException("unexpected method name <"
							+ interfaceMethod.getName()
							+ "> to implement in sbb aci interface");
				}

				if (logger.isTraceEnabled()) {
		            logger.trace("Generated method "
							+ interfaceMethod.getName() + " , body = "
							+ concreteMethodBody);
				}
				concreteMethod.setBody(concreteMethodBody);
				concreteActivityContextInterface.addMethod(concreteMethod);
			} catch (Exception cce) {
				throw new SLEEException("Cannot compile method "
						+ interfaceMethod.getName(), cce);
			}
		}

	}

}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.slee.container.deployment.profile.jpa;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.slee.Address;
import javax.slee.SLEEException;

import org.mobicents.slee.container.profile.entity.ProfileEntity;

/**
 * A class providing static utility methods to deal with conversion of arrays to
 * {@link ProfileEntityArrayAttributeValue} and vice-versa
 *
 * @author martins
 *
 */
public class ProfileAttributeArrayValueUtils {

	/**
	 * TODO
	 * @param profileAttrArrayValueClass
	 * @return
	 */
	private static ProfileEntityArrayAttributeValue newProfileEntityArrayAttributeValueInstance(
			Class<?> profileAttrArrayValueClass,ProfileEntity owner) {
		ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
		try {
			profileAttrArrayValue = (ProfileEntityArrayAttributeValue) profileAttrArrayValueClass
					.newInstance();
			profileAttrArrayValue.setProfileEntity(owner);
		} catch (Throwable e) {
			throw new SLEEException(e.getMessage(), e);
		}
		return profileAttrArrayValue;
	}

	// ----------

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, boolean[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				boolean b = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setboolean(b);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, byte[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				byte b = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setbyte(b);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, char[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				char c = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setchar(c);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, double[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				double d = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setdouble(d);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, float[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				float f = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setfloat(f);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, int[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				int j = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setint(j);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, long[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				long l = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setlong(l);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, short[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				short s = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setshort(s);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Boolean[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Boolean b = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setBoolean(b);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Byte[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Byte b = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setByte(b);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Character[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Character c = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setCharacter(c);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Double[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Double d = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setDouble(d);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Float[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Float f = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setFloat(f);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Integer[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Integer j = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setInteger(j);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Long[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Long l = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setLong(l);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Short[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Short s = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setShort(s);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, String[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				String s = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setString(s);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Address[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Address a = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setAddress(a);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param profileAttrArrayValueClass
	 * @param arg0
	 * @return
	 */
	public static List<ProfileEntityArrayAttributeValue> toProfileAttributeArrayValueList(
			Class<?> profileAttrArrayValueClass, ProfileEntity owner, List<ProfileEntityArrayAttributeValue> result, boolean uniqueAttribute, Serializable[] arg0) {
		// init result list if needed
		if (result == null) {
			result = new ArrayList<ProfileEntityArrayAttributeValue>();
		}
		// make copy of result list if it is not empty
		List<ProfileEntityArrayAttributeValue> copy = null;
		if (!result.isEmpty()) {
			copy = new ArrayList<ProfileEntityArrayAttributeValue>(result);
			result.clear();
		}
		if (arg0 != null) {
			ProfileEntityArrayAttributeValue profileAttrArrayValue = null;
			for (int i=0;i<arg0.length;i++) {
				Serializable s = arg0[i];
				profileAttrArrayValue = newProfileEntityArrayAttributeValueInstance(profileAttrArrayValueClass,owner);
				profileAttrArrayValue.setSerializable(s);
				if (copy != null && i < copy.size()) {
					ProfileEntityArrayAttributeValue existentElement = copy.get(i);
					// reuse element if possible, to avoid unique constraint failures on inserts
					if (existentElement != null && new ProfileAttributeArrayValueIdentity(existentElement).equals(new ProfileAttributeArrayValueIdentity(profileAttrArrayValue))) {
						profileAttrArrayValue = existentElement;
					}
				}
				result.add(profileAttrArrayValue);
			}
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static boolean[] tobooleanArray(
			List<ProfileEntityArrayAttributeValue> list) {
		boolean[] result = new boolean[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getboolean();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static byte[] tobyteArray(List<ProfileEntityArrayAttributeValue> list) {
		byte[] result = new byte[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getbyte();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static char[] tocharArray(List<ProfileEntityArrayAttributeValue> list) {
		char[] result = new char[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getchar();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static double[] todoubleArray(
			List<ProfileEntityArrayAttributeValue> list) {
		double[] result = new double[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getdouble();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static float[] tofloatArray(
			List<ProfileEntityArrayAttributeValue> list) {
		float[] result = new float[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getfloat();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static int[] tointArray(List<ProfileEntityArrayAttributeValue> list) {
		int[] result = new int[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getint();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static long[] tolongArray(List<ProfileEntityArrayAttributeValue> list) {
		long[] result = new long[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getlong();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static short[] toshortArray(
			List<ProfileEntityArrayAttributeValue> list) {
		short[] result = new short[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getshort();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Boolean[] toBooleanArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Boolean[] result = new Boolean[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getBoolean();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Byte[] toByteArray(List<ProfileEntityArrayAttributeValue> list) {
		Byte[] result = new Byte[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getByte();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Character[] toCharacterArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Character[] result = new Character[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getCharacter();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Double[] toDoubleArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Double[] result = new Double[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getDouble();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Float[] toFloatArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Float[] result = new Float[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getFloat();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Integer[] toIntegerArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Integer[] result = new Integer[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getInteger();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Long[] toLongArray(List<ProfileEntityArrayAttributeValue> list) {
		Long[] result = new Long[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getLong();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Short[] toShortArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Short[] result = new Short[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getShort();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static String[] toStringArray(
			List<ProfileEntityArrayAttributeValue> list) {
		String[] result = new String[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getString();
		}
		return result;
	}

	/**
	 *
	 * @param list
	 * @return
	 */
	public static Address[] toAddressArray(
			List<ProfileEntityArrayAttributeValue> list) {
		Address[] result = new Address[list.size()];
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = iterator.next().getAddress();
		}
		return result;
	}

	/**
	 *
	 * @param <T>
	 * @param result
	 * @param list
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T[] toSerializableArray(T[] result,
			List<ProfileEntityArrayAttributeValue> list) {
		Iterator<ProfileEntityArrayAttributeValue> iterator = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			result[i] = (T) iterator.next().getSerializable();
		}
		return result;
	}
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.mobicents.slee.container.management.jmx;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;

import javax.slee.management.ManagementException;

import org.mobicents.slee.container.SleeContainer;
import org.mobicents.slee.container.Version;
import org.mobicents.slee.container.transaction.SleeTransactionManager;

public class MobicentsManagement implements
		MobicentsManagementMBean {

	// Number of minutes after lingering entities of inactive service will be
	// removed.
	public static int entitiesRemovalDelay = 0;

	// restcomm version
	private String mobicentsVersion = Version.instance.toString();

	public int getEntitiesRemovalDelay() {
		return MobicentsManagement.entitiesRemovalDelay;
	}

	public void setEntitiesRemovalDelay(int entitiesRemovalDelay) {
		MobicentsManagement.entitiesRemovalDelay = entitiesRemovalDelay;
	}

	// Flag for initializing SBB CMP fields (with Reference Data Type) with null or 0
	//
	private static Boolean initializeReferenceDataTypesWithNull = false;

	public boolean isInitializeReferenceDataTypesWithNull() {
		return MobicentsManagement.initializeReferenceDataTypesWithNull;
	}

	public void setInitializeReferenceDataTypesWithNull(boolean initializeReferenceDataTypesWithNull) {
		MobicentsManagement.initializeReferenceDataTypesWithNull = initializeReferenceDataTypesWithNull;
	}

	public String getVersion() {
		return mobicentsVersion;
	}

	public String dumpState() throws ManagementException {

		SleeContainer sleeContainer = SleeContainer.lookupFromJndi();
		SleeTransactionManager txManager = sleeContainer
				.getTransactionManager();
		try {
			txManager.begin();
			return sleeContainer.dumpState();
		} catch (Exception e) {
			throw new ManagementException("Failed to get container state", e);
		} finally {
			try {
				txManager.commit();
			} catch (Exception e) {
				throw new ManagementException("Failed to get container state",
						e);
			}
		}
	}

    private static String log4jConfigFilePath = System.getProperty("jboss.server.home.dir") + File.separator + "conf" + File.separator + "jboss-log4j.xml";
    private static String log4jTemplatesPath = System.getProperty("jboss.server.home.dir") + File.separator + "deploy" +
      File.separator + "restcomm-slee" + File.separator + "log4j-templates" + File.separator + "jboss-log4j.xml.";

	/*
	public String getLoggingConfiguration(String profile) throws ManagementException {
	  try {
	    return readFile(getLog4jPath(profile));
	  }
	  catch (IOException ioe) {
	    throw new ManagementException("Failed to read log4j configuration file for profile '" + profile + "'. Does it exists?", ioe);
	  }
	}

    public void setLoggingConfiguration(String profile, String contents) throws ManagementException {
      try {
        writeFile(getLog4jPath(profile), contents);
      }
      catch (IOException ioe) {
        throw new ManagementException("Failed to update log4j configuration file for profile '" + profile + "'.", ioe);
      }
    }

    public void switchLoggingConfiguration(String newProfile) throws ManagementException {
      try {
        // A direct copy would have better performance, but since we
        // already have and need to have these methods, let's use them.
        String srcPath = getLog4jPath(newProfile);
        String destPath = getLog4jPath("");
        writeFile(destPath, readFile(srcPath));
      }
      catch (IOException ioe) {
        throw new ManagementException("Failed to update log4j configuration file for profile '" + newProfile + "'.", ioe);
      }
    }
    */

	private String getLog4jPath(String profile) {
	  return (profile == null || profile.equals("") || profile.equalsIgnoreCase("current")) ? log4jConfigFilePath : log4jTemplatesPath + profile;
	}

	private String readFile(String path) throws IOException {
	  FileInputStream stream = new FileInputStream(new File(path));
	  try {
	    FileChannel fc = stream.getChannel();
	    MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
	    /* Instead of using default, pass in a decoder. */
	    return Charset.defaultCharset().decode(bb).toString();
	  }
	  finally {
	    if(stream != null) {
	      stream.close();
	    }
	  }
	}

	private void writeFile(String path, String contents) throws IOException {
	  BufferedWriter out = new BufferedWriter(new FileWriter(path));
	  try {
	    out.write(contents);
	  }
	  finally {
	    if(out != null) {
	      out.close();
	    }
	  }
	}

}


package javax.slee.management;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.rmi.MarshalledObject;
import javax.slee.facilities.AlarmLevel;

/**
 * The Alarm class contains information about an alarm that has
 * been raised in the SLEE.
 *

 * Serialization of this class takes into account cause Throwable objects that may not
 * be deserializable client-side due to classloader issues.  For example, if the cause
 * of an alarm is an object of a custom exception class included in the deployable unit
 * of a component, a generic client may not have that class available in its classpath
 * or be able to load it via Java's remote class loading mechanisms (eg. the codebase
 * URL could be a file:// URL on a different host that cannot be resolved on the client
 * host).  Serialization of an Alarm object containing a cause includes the
 * stack trace of that cause in the serialization stream.  If the cause Throwable
 * cannot be later deserialized with the Alarm object, a generic
 * java.lang.Exception with a message containing the original stack trace
 * is returned as the alarm's cause instead.
 * @since SLEE 1.1
 */
public final class Alarm implements VendorExtensions, Serializable, Comparable {
    /**
     * Create an Alarm object that contains information about an
     * alarm that has been raised in the SLEE.
     * @param alarmID the unique alarm identifier for the alarm.
     * @param notificationSource the component or subsystem in the SLEE that raised
     *        the alarm.
     * @param alarmType an identifier specifying the type of the alarm.
     * @param instanceID an identifier specifying the particular instance of the
     *        alarm type.
     * @param level the alarm level of the alarm.
     * @param message the reason for the alarm.
     * @param cause an optional cause throwable for the alarm.  May be null
     *        if no cause was provided when the alarm was raised.
     * @param timestamp the time (in ms since January 1, 1970 UTC) that the alarm
     *        was raised.
     * @throws NullPointerException if alarmID, notificationSource,
     *        alarmType, instanceID, level,
     *        or message is null.
     */
    public Alarm(String alarmID, NotificationSource notificationSource, String alarmType, String instanceID, AlarmLevel level, String message, Throwable cause, long timestamp) throws NullPointerException {
        if (alarmID == null) throw new NullPointerException("alarmID is null");
        if (notificationSource == null) throw new NullPointerException("notificationSource is null");
        if (alarmType == null) throw new NullPointerException("alarmType is null");
        if (instanceID == null) throw new NullPointerException("instanceID is null");
        if (level == null) throw new NullPointerException("level is null");
        if (message == null) throw new NullPointerException("message is null");

        this.alarmID = alarmID;
        this.notificationSource = notificationSource;
        this.alarmType = alarmType;
        this.instanceID = instanceID;
        this.level = level;
        this.message = message;
        this.cause = cause;
        this.timestamp = timestamp;
    }

    /**
     * Get the unique alarm identifier for the alarm.
     * @return the alarm identifier.
     */
    public String getAlarmID() {
        return alarmID;
    }

    /**
     * Get the object that identifies the component or subsystem in the SLEE
     * that raised the alarm.
     * @return the notification source.
     */
    public NotificationSource getNotificationSource() {
        return notificationSource;
    }

    /**
     * Get the identifier specifying the type of the alarm, provided when the
     * alarm was raised.
     * @return the type of the alarm.
     */
    public String getAlarmType() {
        return alarmType;
    }

    /**
     * Get the identifier specifying the particular instance of the alarm type,
     * provided when the alarm was raised.
     * @return the alarm instance ID.
     */
    public String getInstanceID() {
        return instanceID;
    }

    /**
     * Get the alarm level of the alarm.
     * @return the alarm level.
     */
    public AlarmLevel getAlarmLevel() {
        return level;
    }

    /**
     * Get the message provided when the alarm was raised.
     * @return the alarm message.
     */
    public String getMessage() {
        return message;
    }

    /**
     * Get the cause provided when the alarm was raised (if any).
     * @return the cause of the alarm, or null if no cause was provided.
     */
    public Throwable getCause() {
        return cause;
    }

    /**
     * Get the time (in ms since January 1, 1970 UTC) that the alarm was raised.
     * @return the time that the alarm was raised.
     */
    public long getTimestamp() {
        return timestamp;
    }

    /**
     * Enable the serialization of vendor-specific data for objects of this class.
     * This method is typically used by a SLEE implementation that wants to export
     * vendor-specific data with objects of this class to management clients.
     *

     * By default, any vendor-specific data included in an object of this class will
     * not be included in the serialization stream when the object is serialized.
     * Invoking this method changes this behavior so that vendor-specific data is
     * included in the serialization stream when an object of this class is serialized.
     *

     * This method should only be invoked if the vendor-specific data is serializable
     * via standard Java serialization means.
     * @see #disableVendorDataSerialization
     * @see #setVendorData
     */
    public static void enableVendorDataSerialization() {
        vendorDataSerializationEnabled = true;
    }

    /**
     * Disable the serialization of vendor-specific data for objects of this class.
     *

     * If the serialization of vendor-specific data for objects of this class has
     * been enabled via the {@link #enableVendorDataSerialization} method, this
     * method disables that behavior again.
     */
    public static void disableVendorDataSerialization() {
        vendorDataSerializationEnabled = false;
    }

    /**
     * Enable the deserialization of vendor-specific data for objects of this class.
     * This method is typically used by a management client that wants to obtain any
     * vendor-specific data included in the serialization stream of objects of this
     * class.
     *

     * By default, any vendor-specific data included in the serialization stream of
     * objects of this class is discarded upon deserialization.  Invoking this method
     * changes that behavior so that the vendor-specific data is also deserialized
     * when an object of this class is deserialized.  A management client that enables
     * the deserialization of vendor-specific data must ensure that any necessary
     * classes required to deserialize that data is available in the relevant
     * classloader.
     * @see #disableVendorDataDeserialization
     * @see #getVendorData
     */
    public static void enableVendorDataDeserialization() {
        vendorDataDeserializationEnabled = true;
    }

    /**
     * Disable the deserialization of vendor-specific data for objects of this class.
     *

     * If the deserialization of vendor-specific data for objects of this class has
     * been enabled via the {@link #enableVendorDataDeserialization} method, this
     * method disables that behavior again.
     */
    public static void disableVendorDataDeserialization() {
        vendorDataDeserializationEnabled = false;
    }

    /**
     * Set the vendor-specific data.
     * @param vendorData the vendor-specific data.
     */
    public void setVendorData(Object vendorData) {
        this.vendorData = vendorData;
    }

    /**
     * Get the vendor-specific data.
     * @return the vendor-specific data.
     */
    public Object getVendorData() {
        return vendorData;
    }

    /**
     * Compare this alarm for equality with another object.
     * @param obj the object to compare this with.
     * @return true if obj is an alarm with the same
     *        notification source, alarm type, and alarm instance ID as this,
     *        false otherwise.
     * @see Object#equals(Object)
     */
    public boolean equals(Object obj) {
        if (obj == this)  return true;
        if (!(obj instanceof Alarm)) return false;

        Alarm that = (Alarm)obj;
        return this.notificationSource.equals(that.notificationSource)
            && this.alarmType.equals(that.alarmType)
            && this.instanceID.equals(that.instanceID);
    }

    /**
     * Get a hash code value for this alarm.  The hash code is calculated from the
     * exclusive-or of the notification source, alarm type, and alarm instance ID.
     * @return a hash code value for this alarm.
     * @see Object#hashCode()
     */
    public int hashCode() {
        return notificationSource.hashCode() ^ alarmType.hashCode() ^ instanceID.hashCode();
    }

    /**
     * Compare this alarm with the specified object for order.
     * Returns a negative integer, zero, or a positive integer if this object
     * is less than, equal to, or greater than the specified object.
     *

     * Alarm ordering is determined by comparing unique the alarm identifier.
     * @param obj the object to compare this with.
     * @return a negative integer, zero, or a positive integer if this alarm
     *        object is considered less than, equal to, or greater than the
     *        specified object.
     * @throws ClassCastException if obj is not an instance of this
     *        class.
     * @see Comparable#compareTo(Object)
     */
    public int compareTo(Object obj) {
        if (obj == this) return 0;
        if (!(obj instanceof Alarm)) throw new ClassCastException("Not a javax.slee.management.Alarm: " + obj);

        Alarm that = (Alarm)obj;
        // compare alarm identifiers
        return this.alarmID.compareTo(that.alarmID);
    }
    /**
     * Get a string representation for this alarm.
     * @see Object#toString()
     */
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("Alarm[id=").append(alarmID).
            append(",source=").append(notificationSource).
            append(",alarmType=").append(alarmType).
            append(",instanceID=").append(instanceID).
            append(",level=").append(level).
            append(",message=").append(message).
            append(",cause=").append(cause).
            append(",timestamp=").append(timestamp);
        if (vendorData != null) buf.append(",vendor data=").append(vendorData);
        buf.append(']');
        return buf.toString();
    }

    // special handling of serialization
    private void writeObject(ObjectOutputStream out) throws IOException {
        VendorExtensionUtils.writeObject(out, vendorDataSerializationEnabled ? vendorData : null);

        if (cause != null) {
            out.writeBoolean(true);
            // serialize the cause inside a marshalled object to isolate
            // the serialized data for it in the stream
            out.writeObject(new MarshalledObject(cause));

            // serialize a text form of the stack trace
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            cause.printStackTrace(pw);
            pw.flush();
            out.writeUTF(sw.getBuffer().toString());
        }
        else {
            out.writeBoolean(false);
        }
    }

    // special handling of deserialization
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        vendorData = VendorExtensionUtils.readObject(in, vendorDataDeserializationEnabled);

        if (in.readBoolean()) {
            // attempt to deserialize the cause
            try {
                cause = (Throwable)((MarshalledObject)in.readObject()).get();
            }
            catch (ClassNotFoundException cnfe) {
                // must have been a class not in standard classloaders and not remotely loadable
                // do nothing now, we'll replace it with the string version included next in the stream
            }
            String causeString = in.readUTF();
            if (cause == null) {
                // replace the cause with a generic exception
                // that includes the original stack trace in its message
                cause = new Exception("Undeserializable cause, original cause stack trace follows: " + causeString);
            }
        }
    }

    private final String alarmID;
    private final NotificationSource notificationSource;
    private final String alarmType;
    private final String instanceID;
    private final AlarmLevel level;
    private final String message;
    private final long timestamp;
    private transient Throwable cause;

    private static volatile boolean vendorDataSerializationEnabled = false;
    private static volatile boolean vendorDataDeserializationEnabled = false;
    private transient Object vendorData;
}


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * Start time:00:45:25 2009-02-04

 * Project: restcomm-jainslee-server-core

 *
 * @author baranowb - Bartosz Baranowski
 *
 * @author  Alexandre Mendonca
 */
package org.mobicents.slee.container.component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.slee.ComponentID;
import javax.slee.management.ComponentDescriptor;
import javax.slee.management.DependencyException;
import javax.slee.management.DeploymentException;
import javax.slee.management.LibraryID;
import javax.slee.profile.ProfileSpecificationID;
import javax.slee.resource.ConfigProperties;
import javax.slee.resource.ResourceAdaptorID;
import javax.slee.resource.ResourceAdaptorTypeID;

import org.mobicents.slee.container.component.UsageParameterDescriptor;
import org.mobicents.slee.container.component.common.ProfileSpecRefDescriptor;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.ResourceAdaptorDescriptorImpl;
import org.mobicents.slee.container.component.ra.ConfigPropertyDescriptor;
import org.mobicents.slee.container.component.ra.ResourceAdaptorComponent;
import org.mobicents.slee.container.component.security.PermissionHolderImpl;

/**
 * Start time:00:45:25 2009-02-04

 * Project: restcomm-jainslee-server-core

 *
 * @author baranowb - Bartosz Baranowski
 *
 * @author  Alexandre Mendonca
 */
public class ResourceAdaptorComponentImpl extends AbstractSleeComponentWithUsageParametersInterface implements ResourceAdaptorComponent {

	/**
	 * the ra descriptor
	 */
	private final ResourceAdaptorDescriptorImpl descriptor;

	/**
	 * the ra class
	 */
	private Class<?> resourceAdaptorClass = null;

	/**
	 * the JAIN SLEE specs descriptor
	 */
	private javax.slee.resource.ResourceAdaptorDescriptor specsDescriptor = null;

	/**
	 *
	 * @param descriptor
	 */
	public ResourceAdaptorComponentImpl(ResourceAdaptorDescriptorImpl descriptor) {
		this.descriptor = descriptor;
	}

	/**
	 * Retrieves the ra descriptor
	 *
	 * @return
	 */
	public ResourceAdaptorDescriptorImpl getDescriptor() {
		return descriptor;
	}

	/**
	 * Retrieves the ra id
	 *
	 * @return
	 */
	public ResourceAdaptorID getResourceAdaptorID() {
		return descriptor.getResourceAdaptorID();
	}

	/**
	 * Retrieves the ra class
	 *
	 * @return
	 */
	public Class<?> getResourceAdaptorClass() {
		return resourceAdaptorClass;
	}

	/**
	 * Sets the ra class
	 *
	 * @param resourceAdaptorClass
	 */
	public void setResourceAdaptorClass(Class<?> resourceAdaptorClass) {
		this.resourceAdaptorClass = resourceAdaptorClass;
	}

	@Override
	public boolean addToDeployableUnit() {
		return getDeployableUnit().getResourceAdaptorComponents().put(getResourceAdaptorID(), this) == null;
	}

	@Override
	public Set<ComponentID> getDependenciesSet() {
		return descriptor.getDependenciesSet();
	}

	@Override
	public ComponentID getComponentID() {
		return getResourceAdaptorID();
	}

	@Override
	public boolean isSlee11() {
		return descriptor.isSlee11();
	}

	@Override
	public boolean validate() throws DependencyException, DeploymentException {
		// FIXME use validator when available
		return true;
	}

	/**
	 * Retrieves the JAIN SLEE specs descriptor
	 *
	 * @return
	 */
	public javax.slee.resource.ResourceAdaptorDescriptor getSpecsDescriptor() {
		if (specsDescriptor == null) {
			final LibraryID[] libraryIDs = descriptor.getLibraryRefs().toArray(new LibraryID[descriptor.getLibraryRefs().size()]);
			final ResourceAdaptorTypeID[] raTypeIDs = descriptor.getResourceAdaptorTypeRefs().toArray(new ResourceAdaptorTypeID[descriptor.getResourceAdaptorTypeRefs().size()]);
			Set<ProfileSpecificationID> profileSpecSet = new HashSet<ProfileSpecificationID>();
			for (ProfileSpecRefDescriptor mProfileSpecRef : descriptor.getProfileSpecRefs()) {
				profileSpecSet.add(mProfileSpecRef.getComponentID());
			}
			ProfileSpecificationID[] profileSpecs = profileSpecSet.toArray(new ProfileSpecificationID[profileSpecSet.size()]);
			specsDescriptor = new javax.slee.resource.ResourceAdaptorDescriptor(getResourceAdaptorID(), getDeployableUnit().getDeployableUnitID(), getDeploymentUnitSource(), libraryIDs, raTypeIDs, profileSpecs,
					getDescriptor().getSupportsActiveReconfiguration());
		}
		return specsDescriptor;
	}

	@Override
	public ComponentDescriptor getComponentDescriptor() {
		return getSpecsDescriptor();
	}

	/**
	 * Creates an instance of the {@link ConfigProperties} for this component
	 *
	 * @return
	 */
	public ConfigProperties getDefaultConfigPropertiesInstance() {
		ConfigProperties defaultProperties = new ConfigProperties();
		for (ConfigPropertyDescriptor mConfigProperty : getDescriptor().getConfigProperties()) {
			Object configPropertyValue = mConfigProperty.getConfigPropertyValue() == null ? null : ConfigProperties.Property.toObject(mConfigProperty.getConfigPropertyType(), mConfigProperty
					.getConfigPropertyValue());
			defaultProperties.addProperty(new ConfigProperties.Property(mConfigProperty.getConfigPropertyName(), mConfigProperty.getConfigPropertyType(), configPropertyValue));
		}
		return defaultProperties;
	}

	@Override
	public void processSecurityPermissions() throws DeploymentException {
		try {
			if (this.descriptor.getSecurityPermissions() != null) {
				super.permissions.add(new PermissionHolderImpl(super.getDeploymentDir().toURI(), this.descriptor.getSecurityPermissions()));
			}
		} catch (Exception e) {
			throw new DeploymentException("Failed to make permissions usable.", e);
		}
	}

	@Override
	public void undeployed() {
		super.undeployed();
		specsDescriptor = null;
		resourceAdaptorClass = null;
	}

	/* (non-Javadoc)
	 * @see org.mobicents.slee.container.component.AbstractSleeComponentWithUsageParametersInterface#getUsageParametersList()
	 */
	@Override
	public List<UsageParameterDescriptor> getUsageParametersList() {
		return descriptor.getResourceAdaptorUsageParametersInterface().getUsageParameter();
	}
}