/*
 * This software is distributed under following license based on modified BSD
 * style license.
 * ----------------------------------------------------------------------
 * 
 * Copyright 2009 The Nimbus2 Project. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE NIMBUS PROJECT ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE NIMBUS PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the Nimbus2 Project.
 */
package jp.ossc.nimbus.service.writer;

import java.util.*;

import jp.ossc.nimbus.beans.Property;
import jp.ossc.nimbus.core.ServiceBaseMBean;
import jp.ossc.nimbus.core.ServiceName;

/**
 * {@link DefaultWritableRecordFactoryService}のMBeanインタフェース。<p>
 * 
 * @author Y.Tokuda
 */
public interface DefaultWritableRecordFactoryServiceMBean extends ServiceBaseMBean {
    
    /**
     * {@link WritableRecordFactory#createRecord(Object)}で指定されたマップのキーに対するWritableElement実装クラスを設定する。<p>
     * このメソッドで設定されなかったキーに対しては、{@link SimpleElement}がマッピングされる。<br>
     * 
     * @param key キー
     * @param clazz WritableElement実装クラス
     */
    public void setWritableElementClass(String key, Class<WritableElement> clazz);
    
    /**
     * {@link WritableRecordFactory#createRecord(Object)}で指定されたマップのキーに対するWritableElement実装クラスを取得する。<p>
     * 
     * @param key キー
     * @return WritableElement実装クラス
     */
    public Class<WritableElement> getWritableElementClass(String key);
    
    /**
     * {@link WritableRecordFactory#createRecord(Object)}で指定されたマップのキーに対するWritableElement実装サービス名を設定する。<p>
     * WritableElementインスタンスは、その都度生成される必要があるので、{@link jp.ossc.nimbus.core.FactoryService FactoryService}を実装したサービスを使用するか、service要素のinstance属性でfactoryを指定すること。<br>
     * このメソッドで指定されなかったキーに対しては、{@link SimpleElement}がマッピングされる。<br>
     * 
     * @param key キー
     * @param name WritableElement実装サービス名
     */
    public void setWritableElementServiceName(String key, ServiceName name);
    
    /**
     * {@link WritableRecordFactory#createRecord(Object)}で指定されたマップのキーに対するWritableElement実装サービス名を取得する。<p>
     * 
     * @return WritableElement実装サービス名
     */
    public ServiceName getWritableElementServiceName(String key);
    
    /**
     * 出力フォーマットを設定する。<p>
     * フォーマットには、キーと、キー以外の任意の文字列を使用できる。キーの指定は、キー名を"%"で囲む。"%"をキーのセパレータ以外の文字として使いたい場合は、"\"を前に付けてエスケープする。"\"をエスケープ文字以外として使いたい場合は、"\"を2回重ねる。<br>
     * キーは、{@link WritableRecordFactory#createRecord(Object)}で指定する引数がMapならば、Mapのキー名をそのまま指定する。引数が任意のBeanである場合は、キーは抽象的な名前とし、{@link #setFormatKeyProperty(String, Property)}で、   そのキーがBeanのどのようなプロパティ値にあたるかを設定する。また、Beanのプロパティが繰り返し構造を持つ場合には、キー名の後ろに"*"を付与する。繰り返し構造のフォーマットは、{@link #setIterateFormat(String)}で指定する。<br>
     * <pre>
     *  例：[%DATE%] %MESSAGES*%
     * </pre>
     *
     * @param format フォーマット文字列
     */
    public void setFormat(String format);
    
    /**
     * {@link WritableRecordFactory#createRecord(Object)}で指定されたマップの値のフォーマットを取得する。<p>
     *
     * @return フォーマット文字列
     */
    public String getFormat();
    
    /**
     * キーに対するBeanのプロパティを設定する。<p>
     * {@link WritableRecordFactory#createRecord(Object)}で指定する引数が任意のBeanである場合、Beanからどのように値を取得するかをプロパティとして設定する。<br>
     * <pre>
     *  例：
     *   Beanに getDate() メソッドがある場合
     *       &lt;attribute name="FormatKeyProperty(DATE)"&gt;Date&lt;/attribute&gt;
     *   Beanに getMessageList() メソッドがある場合
     *       &lt;attribute name="FormatKeyProperty(MESSAGES*)"&gt;MessageList&lt;/attribute&gt;
     * </pre>
     *
     * @param key キー
     * @param prop Beanのプロパティ
     */
    public void setFormatKeyProperty(String key, Property prop);
    
    /**
     * キーに対するBeanのプロパティを取得する。<p>
     *
     * @param key キー
     * @return Beanのプロパティ
     */
    public Property getFormatKeyProperty(String key);
    
    /**
     * キーに対するBeanのプロパティを設定する。<p>
     * {@link WritableRecordFactory#createRecord(Object)}で指定する引数が任意のBeanである場合、Beanからどのように値を取得するかをプロパティとして設定する。<br>
     * <pre>
     *  例：
     *   Beanに getDate() メソッドとgetMessageList() メソッドがある場合
     *       &lt;attribute name="FormatKeyProperty"&gt;
     *           DATE=Date
     *           MESSAGES*=MessageList
     *       &lt;/attribute&gt;
     * </pre>
     *
     * @param mapping 繰り返しフォーマットで指定したキーとプロパティのマッピング
     */
    public void setFormatKeyMapping(Properties mapping);
    
    /**
     * キーに対するBeanのプロパティを取得する。<p>
     *
     * @return フォーマットで指定したキーとプロパティのマッピング
     */
    public Properties getFormatKeyMapping();
    
    /**
     * 繰り返し構造のフォーマットを設定する。<p>
     * フォーマットの指定方法は、{@link #setFormat(String)}に準じる。<br>
     * <pre>
     *  例：
     *    &lt;attribute name="IterateFormat(MESSAGES*)"&gt;%ID%:%MESSAGE%,&lt;/attribute&gt;
     * </pre>
     *
     * @param key 繰り返しキー
     * @param format フォーマット文字列
     */
    public void setIterateFormat(String key, String format);
    
    /**
     * 繰り返し構造のフォーマットを取得する。<p>
     *
     * @param key 繰り返しキー
     * @return フォーマット文字列
     */
    public String getIterateFormat(String key);
    
    /**
     * 繰り返しキーに対するBeanのプロパティを設定する。<p>
     * {@link WritableRecordFactory#createRecord(Object)}で指定する引数が任意のBeanである場合、Beanからどのように値を取得するかをプロパティとして設定する。<br>
     * <pre>
     *  例：
     *   繰り返し要素のBeanに getId() メソッドと、getMessage() メソッドがある場合
     *       &lt;attribute name="IterateFormatKeyMapping(MESSAGES*)"&gt;
     *           ID=Id
     *           MESSAGE=Message
     *       &lt;/attribute&gt;
     * </pre>
     *
     * @param key 繰り返しキー
     * @param mapping 繰り返しフォーマットで指定したキーとプロパティのマッピング
     */
    public void setIterateFormatKeyMapping(String key, Properties mapping);
    
    /**
     * 繰り返しキーに対するBeanのプロパティを取得する。<p>
     *
     * @param key 繰り返しキー
     * @return 繰り返しフォーマットで指定したキーとプロパティのマッピング
     */
    public Properties getIterateFormatKeyMapping(String key);
}
