/*
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 *     Loetz GmbH&Co.KG                               
 * 
 */

package org.eclipse.osbp.webserver.messagequeue;

import java.util.Map;

import javax.jms.JMSException;
import javax.jms.MapMessage;

/**
 * Dieses gesamte Package muss zum jetzigen Zeitpunkt <b>manuell</b> dupliziert und synchronisiert werden<ul>
 * <li><a href="http://10.1.2.27:8100/cc360/browser/OSGI-Plugins/org.eclipse.osbp.webserver.messagequeue">cc360/OSGI-Plugins/org.eclipse.osbp.webserver.messagequeue</a></li>
 * <li><a href="http://10.1.2.27:8100/kapstadt/browser/development2/3.50/src/cxj/diamond7/src/webclt-webserver/org/eclipse/osbp/webserver/messagequeue">cc3.50/development2/3.50/src/cxj/diamond7/src/webclt-webserver/org/eclipse/osbp/webserver/messagequeue</a></li>
 * </ul>
 * All available attributes inside a ActiveMQ message!
 * TODO should depend on {@link ECXMqMessageEvent}
 */
public enum ECXMqMessageAttribute {
	//
	/** any ccng perpective id. */
	PERSPECTIVE_ID,
	
	/** The title. */
	//
	TITLE,
	
	/** icon data. */
	ICON_URI,
	
	/** The icon serialized. */
	ICON_SERIALIZED,
	//
	/** queuename for ActiveMQ. */
	CCNG_QUEUENAME,
	//
    /** credentials for authentication - portal id. */
	PORTAL_ID,
    
    /** credentials for authentication - username. */
	USERNAME,
    
    /** credentials for authentication - password. */
	PASSWORD,
	//
	/** legacy program call. */
	LEGACY_PROGRAMCALL,
    //
    /** fallback for unknown attributes. */
	UNKNOWN;

	/**
	 * set the value for the attribute into the message TODO should depend on
	 * the type of event .
	 *
	 * @param message
	 *            the message
	 * @param value
	 *            the value
	 */
	public void setValue(MapMessage message, Object value) {
		try {
			message.setObjectProperty(toString(), value);
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Gets the value.
	 *
	 * @param message
	 *            the message
	 * @return the value of the attribute inside the message
	 */
	public Object getValue(MapMessage message) {
		try {
			return message.getObjectProperty(toString());
		} catch (JMSException e) {}
		return null;
	}
	
	/**
	 * Gets the value.
	 *
	 * @param body
	 *            the body
	 * @return the value of the attribute inside the message
	 */
	public Object getValue(Map<ECXMqMessageAttribute, Object> body) {
		Object value = body.get(toString());
		if	(value == null) {
			value = body.get(this);
		}
		return value;
	}
}
