package org.analogweb.core.direction;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.analogweb.DirectionFormatter;
import org.analogweb.DirectionFormatterAware;
import org.analogweb.DirectionFormatters;
import org.analogweb.RequestContext;
import org.analogweb.exception.FormatFailureException;

/**
 * テキストフォーマットが可能な{@link org.analogweb.Direction}の実装です。
 * @author snowgoose
 */
public abstract class TextFormattable<T extends TextFormattable<T>> extends TextFormat<T> implements DirectionFormatterAware<T> {

    private Object source;
    private DirectionFormatter formatter;

    /**
     * 特定のインスタンスをテキストにフォーマットし、ストリームに書き出します。
     * インスタンスをテキストフォーマットする実装を入れ替える為に使用します。
     * @author snowgoose
     */
    public static interface ReplaceableFormatWriter {
        void write(RequestContext writeTo, String charset, Object source)
                throws FormatFailureException;
    }

    public TextFormattable() {
        super();
    }

    public TextFormattable(String input, String contentType, String charset) {
        super(input, contentType, charset);
    }

    public TextFormattable(String input) {
        super(input);
    }

    public TextFormattable(Object source) {
        this.source = source;
    }

    protected Object getSource() {
        return this.source;
    }

    /**
     * 現在のフォーマット可能な{@link DirectionFormatter}を取得します。<br/>
     * 自分のクラスに適切な{@link DirectionFormatter}が
     * {@link DirectionFormatters}のインスタンスに登録されている必要があります。
     * @return {@link ReplaceableFormatWriter}
     */
    protected DirectionFormatter getFormatter() {
        return this.formatter;
    }

    @Override
    public void render(RequestContext context) throws IOException, ServletException {
        HttpServletResponse response = context.getResponse();
        response.setContentType(getContentType());
        Object toXml = getSource();
        if (toXml == null) {
            super.writeToStream(response.getOutputStream());
            return;
        }
        DirectionFormatter formatter = getFormatter();
        if (formatter == null) {
            formatter = getDefaultFormatter();
        }
        formatter.formatAndWriteInto(context, getCharset(), toXml);
    }

    /**
     * デフォルトの{@link ReplaceableFormatWriter}によって特定のフォーマットへのレンダリングを行います。<br/>
     * この{@link ReplaceableFormatWriter}は全ての{@link TextFormattable}のインスタンスに適用されます。
     */
    protected abstract DirectionFormatter getDefaultFormatter();

    /**
     * 指定した{@link DirectionFormatter}によって特定のフォーマットのレンダリングを行います。<br/>
     * @param <T> フォーマットする対象の型
     * @param formatter {@link DirectionFormatter}
     */
    @Override
    @SuppressWarnings("unchecked")
    public T attach(DirectionFormatter formatter) {
        this.formatter = formatter;
        return (T)this;
    }
    

}

@@ -317,63 +317,8 @@
 ext;
-%0Aimport org.analogweb.exception.FormatFailureException;
 %0A%0A/*
@@ -499,16 +499,24 @@
 plements
+%0A       
  Directi
@@ -612,318 +612,8 @@
 r;%0A%0A
-    /**%0A     * %E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%82%92%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%97%E3%80%81%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%81%AB%E6%9B%B8%E3%81%8D%E5%87%BA%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%0A     * %E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%82%92%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%99%E3%82%8B%E5%AE%9F%E8%A3%85%E3%82%92%E5%85%A5%E3%82%8C%E6%9B%BF%E3%81%88%E3%82%8B%E7%82%BA%E3%81%AB%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%0A     * @author snowgoose%0A     */%0A    public static interface ReplaceableFormatWriter %7B%0A        void write(RequestContext writeTo, String charset, Object source)%0A                throws FormatFailureException;%0A    %7D%0A%0A
     
@@ -2481,16 +2481,17 @@
 turn (T)
+ 
 this;%0A  
@@ -2493,17 +2493,12 @@
 s;%0A    %7D
-%0A    
 %0A%0A%7D%0A

Remove ReplaceableFormatWriter