/*
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * 
 * $Id: TemplateWriterInterceptor.java 69518 2013-01-15 15:47:01Z supol $ 
 */

package com.sun.ts.tests.jaxrs.ee.rs.ext.interceptor.writer;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;

import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

import com.sun.ts.tests.jaxrs.api.rs.ext.interceptor.InterceptorCallbackMethods;
import com.sun.ts.tests.jaxrs.api.rs.ext.interceptor.TemplateInterceptorBody;

/**
 * This class is a superclass for any interceptor @Provider. Any such provider
 * is then given a body, inherited from TemplateInterceptorBody. The body
 * actually contains methods with name equalIgnoreCase to ContextOperation items
 * name, the name of the method executed is passed by http header OPERATION
 * 
 * @see TemplateInterceptorBody
 * 
 *      The injection of the body solves the issue with inheritance from two
 *      super-classes.
 */
public abstract class TemplateWriterInterceptor implements WriterInterceptor,
		InterceptorCallbackMethods {

	protected WriterInterceptorContext writerCtx;
	protected TemplateInterceptorBody<WriterInterceptorContext> interceptorBody;

	public TemplateWriterInterceptor(
			TemplateInterceptorBody<WriterInterceptorContext> interceptorBody) {
		super();
		this.interceptorBody = interceptorBody;
	}

	@Override
	public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException {
		this.writerCtx = ctx;
		interceptorBody.executeMethod(writerCtx, this);
	}

	@Override
	public void writeEntity(String entity) {
		Type type = writerCtx.getGenericType();
		if (type instanceof Class) {
			Class<?> clazz = ((Class<?>) type);
			if (clazz == InputStreamReader.class) {
				ByteArrayInputStream bis = new ByteArrayInputStream(
						entity.getBytes());
				InputStreamReader reader = new InputStreamReader(bis);
				writerCtx.setEntity(reader);
			} else {
				writerCtx.setEntity(entity);
			}
		}
	}

	@Override
	public Object proceed() throws IOException {
		writerCtx.proceed();
		return null;
	}

	@Override
	public String getHeaderString() {
		MultivaluedMap<String, Object> headers = writerCtx.getHeaders();
		return (String) headers.getFirst(TemplateInterceptorBody.OPERATION);
	}

}
