/*
 *                                                                            
 *  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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 *     Loetz GmbH&Co.KG                               
 * 
 */

package org.eclipse.osbp.webserver.messagequeue;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

// @see 
/**
 * 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>
 */
public class CXMqOneWayCoder {
	
	/** The md. */
	private MessageDigest fMd;

	/**
	 * Encode.
	 *
	 * @param data
	 *            the data
	 * @return encoded data via MD5
	 */
	protected static String encode(String data) {
		return encode("MD5", data);
	}
	
	/**
	 * Encode.
	 *
	 * @param algorithm
	 *            the algorithm
	 * @param data
	 *            the data
	 * @return encoded data via algorithm
	 */
	protected static String encode(String algorithm, String data) {
		CXMqOneWayCoder coder = new CXMqOneWayCoder(algorithm);
		return coder.doEncode(data);
	}
	
	/**
	 * Instantiates a new CX mq one way coder.
	 *
	 * @param algorithm
	 *            the algorithm
	 */
	private CXMqOneWayCoder(String algorithm) {
		try {
			fMd = MessageDigest.getInstance(algorithm);
		} catch(NoSuchAlgorithmException nsae) {
			nsae.printStackTrace();
		}
	}

  	/** To hex string.
		 *
		 * @param b
		 *            the b
		 * @return the string
		 */
	  private String toHexString(byte b) {
   		int value = (b & 0x7F) + (b < 0 ? 128 : 0);
	   
    		String ret = (value < 16 ? "0" : "");
    		ret += Integer.toHexString(value).toUpperCase();
	    
		return ret;
  	}

	/**
	 * Do encode.
	 *
	 * @param data
	 *            the data
	 * @return the string
	 */
	private String doEncode(String data) {
		StringBuffer strbuf = new StringBuffer();
		byte[] digest;
		
		fMd.update(data.getBytes(), 0, data.length());      
  		digest = fMd.digest();      

  		for (int i = 0; i < digest.length; i++) {
  			strbuf.append(toHexString(digest[i]));
		}
		return strbuf.toString();
 	}
}
