/*
 * $Id: FeatConfig.java 220 2007-07-16 10:32:15Z sugimotokenichi $
 * Copyright (C) 2005 SUGIMOTO Ken-ichi
 * 作成日: 2006/02/17
 */
package feat2.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;

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

/**
 * feat設定ファイルの情報。
 * @author SUGIMOTO Ken-ichi
 */
public class FeatConfig extends Config {

    /** validateメソッドが呼ばれるまでここにfeatureを保管しておく */
    private ArrayList featureList;
    /** validateメソッドでFeatureConfigをこのマップに移し変える */
    private HashMap features;
    private Resources resources;
    private FileLocator configFileLocator;
    private FileLocator appRootLocator;
    private boolean useBodyEncodingForURI;
    private int httpPort;
    private int httpsPort;

    public FeatConfig() {
        featureList = new ArrayList();
        features = null;
        resources = new Resources();
        useBodyEncodingForURI = false;
        httpPort = -1;
        httpsPort = -1;
    }

    public void addFeatureConfig(FeatureConfig feature) {
        featureList.add(feature);
        feature.setParent(this);
    }

    /**
     * フィーチャーの設定を返す。
     * @param featureName
     * @return
     * @throws IllegalStateException validateメソッドが呼ばれる前にgetFeatureConfigメソッドが呼ばれたときにスローされる
     */
    public FeatureConfig getFeatureConfig(String featureName) throws IllegalStateException{
        if ( features == null )
            throw new IllegalStateException("validateメソッドが呼ばれる前にgetFeatureConfigメソッドが呼ばれました");
        return (FeatureConfig)features.get(featureName);
    }

    public void addResources(Resources resources) {
        this.resources.addResources(resources);
    }

    public String getStringResource(String resourceName, Locale locale) {
        return resources.getString(resourceName, locale);
    }

    public Resources getResources() {
        return resources;
    }

    public Iterator getFeatures() {
        return featureList.iterator();
    }

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

    public FileLocator getAppRootLocator() {
        return appRootLocator;
    }
    public void setAppRootLocator(FileLocator appRootLocator) {
        this.appRootLocator = appRootLocator;
    }

    public FileLocator getConfigFileLocator() {
        return configFileLocator;
    }
    public void setConfigFileLocator(FileLocator configFileLocator) {
        this.configFileLocator = configFileLocator;
    }

    public Identifier getName() {
        return null;
    }

    public boolean isUseBodyEncodingForURI() {
        return useBodyEncodingForURI;
    }

    public void setUseBodyEncodingForURI(boolean useBodyEncodingForURI) {
        this.useBodyEncodingForURI = useBodyEncodingForURI;
    }

    public int getHttpPort() {
        return httpPort;
    }
    public void setHttpPort(int httpPort) {
        this.httpPort = httpPort;
    }

    public int getHttpsPort() {
        return httpsPort;
    }
    public void setHttpsPort(int httpsPort) {
        this.httpsPort = httpsPort;
    }


    // Configのメソッド -------------------------------------------------------

    public String getElementName() {
        return "feat";
    }

    public boolean validate(FeatErrors errs) {

        boolean ret = true;

        if ( !useBodyEncodingForURI )
            errs.add( new ConfigError(null, "warn.config.feat.useBodyEncodingForURI.false", FeatError.WARN, this) );

        features = new HashMap();
        for (Iterator iter = featureList.iterator(); iter.hasNext();) {
            FeatureConfig featureConf = (FeatureConfig) iter.next();
            features.put(featureConf.getName().getValue(), featureConf);
        }

        ret = ( ret && ConfigUtil.validate(featureList.iterator(), errs) );

        if ( configFileLocator == null )
            throw new ConfigurationException("exception.config.feat.configFileLocator.null");
        if ( appRootLocator == null )
            throw new ConfigurationException("exception.config.feat.appRootLocator.null");

        return ret;
    }


}
