/*
 * $Id: Config.java,v 1.3 2006/04/20 15:30:44 sugimotokenichi Exp $
 * Copyright (C) 2005 SUGIMOTO Ken-ichi
 * 作成日: 2006/02/17
 */
package feat2.config;

import feat2.FeatErrors;
import feat2.config.type.Identifier;


/**
 * 設定の基本クラス。
 * @author SUGIMOTO Ken-ichi
 */
abstract public class Config {

    private Config parent;
    //private ErrorHandler errorHandler;

    // プロパティ -------------------------------------------------------------

    public Config getParent() {
        return parent;
    }
    public void setParent(Config parent) {
        this.parent = parent;
    }

    /**
     * 設定ファイルの要素名を返す。
     */
    abstract public String getElementName();

    /**
     * 設定ノードのインスタンスの名前を返す。
     * @return 名前が無い場合はnullを返す
     */
    abstract public Identifier getName();

    // インスタンスメソッド ---------------------------------------------------

    /*public void handleError(String errorCode) {
        errorHandler.handleError(errorCode, getConfigPath());
    }*/

    /**
     * FeatConfigのインスタンスを検索する。
     * @return FeatConfigのインスタンス。見つからなかったらnull。
     */
    public FeatConfig getFeatConfig() {
        return (FeatConfig)getConfig(FeatConfig.class);
    }

    public FeatureConfig getFeatureConfig() {
        return (FeatureConfig)getConfig(FeatureConfig.class);
    }

    private Config getConfig(Class type) {
        for(Config cur = this; cur != null; cur = cur.getParent()){
            if ( cur instanceof Config && type.isInstance(cur) )
                return (Config)cur;
        }
        return null;
    }

    /**
     * この設定オブジェクトのツリー上の位置を表す文字列を返す。
     * @return
     */
    public String getConfigPath() {
        StringBuffer buf = new StringBuffer();
        for(Config cur = this; cur != null; cur = cur.getParent()) {

            if ( buf.length() > 0 )
                buf.insert(0, "/");

            StringBuffer elembuf = new StringBuffer();
            elembuf.append(cur.getElementName());

            if ( cur.getName() != null ) {
                elembuf.append("[").append(cur.getName().getValue()).append("]");
            }

            buf.insert(0, elembuf.toString());

            if ( cur instanceof FeatConfig || cur instanceof FeatureRootConfig )
                break;

        }
        return buf.toString();
    }

    /*public void setErrorHandler(ErrorHandler handler) {
        errorHandler = handler;
    }*/

    abstract public boolean validate(FeatErrors errs);

}
