package com.tsystems.etc.bpel;

import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import javax.resource.ResourceException;
import javax.resource.cci.InteractionSpec;
import oracle.tip.adapter.api.exception.PCResourceException;
import oracle.tip.adapter.api.exception.PCRetriableResourceException;
import org.apache.log4j.Logger;
import com.sap.mw.jco.JCO;

public class SAPExceptionFilter implements oracle.tip.adapter.api.exception.ExceptionFilter {
	private static final String REGEX = ".*com\\.sap\\.mw\\.jco\\.JCO\\$\\w*Exception: \\((\\d{3})\\) (JCO|RFC)_ERROR_[A-Z_]+: .*";
	private static final Pattern PATTERN = Pattern.compile(REGEX, Pattern.DOTALL);
	private static final Logger LOGGER = Logger.getLogger("handlers.collaxa.cube.engine");
	public void init(InteractionSpec spec, Map props) {
		LOGGER.info(this + ".init(): " + spec);
		LOGGER.info(this + ".init(): " + props);
	}
	public PCResourceException applyFilter(ResourceException rex) {
		Exception ex = rex.getLinkedException();
		String msg = ex != null ? ex.getMessage() : null;
		int group = -1;
		// Extract JCO error code
		if (msg != null) {
			Matcher m = PATTERN.matcher(msg);
			if (m.matches()) {
				group = Integer.parseInt(m.group(1));
			}
		}
		// Retriable if JCO_ERROR_COMMUNICATION or JCO_ERROR_LOGON_FAILURE
		PCResourceException pcex = null;
		switch (group) {
			case JCO.Exception.JCO_ERROR_COMMUNICATION:
			case JCO.Exception.JCO_ERROR_LOGON_FAILURE:
				pcex = new PCRetriableResourceException(rex);
			break;
			default:
				pcex = new PCResourceException(rex);
		}
		// Set error message and code
		if (msg != null) {
			pcex.setEISErrorMessage(msg);
		}
		pcex.setEISErrorCode(String.valueOf(group));
		LOGGER.info(this + ".applyFilter(): " + rex + " linked to " + ex + " wrapped with " + pcex.getClass().getName());
		return pcex;
	}
	public void destroy() {}
}
