Package com.asakusafw.compiler.flow

Source Code of com.asakusafw.compiler.flow.FlowDescriptionDriver

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.compiler.flow;

import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import com.asakusafw.compiler.common.Precondition;
import com.asakusafw.utils.collections.Lists;
import com.asakusafw.vocabulary.external.ExporterDescription;
import com.asakusafw.vocabulary.external.ImporterDescription;
import com.asakusafw.vocabulary.flow.FlowDescription;
import com.asakusafw.vocabulary.flow.In;
import com.asakusafw.vocabulary.flow.Out;
import com.asakusafw.vocabulary.flow.graph.FlowGraph;
import com.asakusafw.vocabulary.flow.graph.FlowIn;
import com.asakusafw.vocabulary.flow.graph.FlowOut;
import com.asakusafw.vocabulary.flow.graph.InputDescription;
import com.asakusafw.vocabulary.flow.graph.OutputDescription;


/**
* {@link FlowDescription}を結線するドライバ。
*/
public class FlowDescriptionDriver {

    private final List<Object> ports = Lists.create();

    private final Map<String, FlowIn<?>> inputs = new LinkedHashMap<String, FlowIn<?>>();

    private final Map<String, FlowOut<?>> outputs = new LinkedHashMap<String, FlowOut<?>>();

    /**
     * 指定の名前とインポーター記述を持つ入力を作成する。
     * <p>
     * 入力の名前は、同一のフロー記述における入力内で重複してはならない。
     * また、識別子には、下記の形式の名前 (Javaの変数名のうち、ASCIIコード表に収まるもののみ)
     * を利用可能である。
     * </p>
<pre><code>
Name :
    NameStart NamePart*
NameStart: one of
    A-Z
    a-z
    _
NamePart: one of
    NameStart
    0-9
</code></pre>
     * @param <T> 入力データの型
     * @param name 入力の名前
     * @param importer 入力に利用するインポーターの名前
     * @return 作成した入力オブジェクト
     * @throws IllegalStateException すでに指定の名前の入力が存在する場合
     * @throws IllegalArgumentException 引数に不正な名前、または{@code null}が指定された場合
     */
    public <T> In<T> createIn(String name, ImporterDescription importer) {
        Precondition.checkMustNotBeNull(name, "name"); //$NON-NLS-1$
        Precondition.checkMustNotBeNull(importer, "importer"); //$NON-NLS-1$
        if (isValidName(name) == false) {
            throw new IllegalArgumentException(MessageFormat.format(
                    "入力の名前が不正です ({0})",
                    name));
        }
        if (inputs.containsKey(name)) {
            throw new IllegalStateException(MessageFormat.format(
                    "入力の名前が重複しています ({0})",
                    name));
        }
        FlowIn<T> in = new FlowIn<T>(new InputDescription(name, importer));
        inputs.put(name, in);
        ports.add(in);
        return in;
    }

    /**
     * 指定の名前とエクスポーター記述を持つ出力を作成する。
     * <p>
     * 出力の名前は、同一のフロー記述における出力内で重複してはならない。
     * また、識別子には、下記の形式の名前 (Javaの変数名のうち、ASCIIコード表に収まるもののみ)
     * を利用可能である。
     * </p>
<pre><code>
Name :
    NameStart NamePart*
NameStart: one of
    A-Z
    a-z
    _
NamePart: one of
    NameStart
    0-9
</code></pre>
     * @param <T> 出力データの型
     * @param name 出力の名前
     * @param exporter 出力に利用するエクスポーターの名前
     * @return 作成した出力オブジェクト
     * @throws IllegalStateException すでに指定の名前の出力が存在する場合
     * @throws IllegalArgumentException 引数に不正な名前、または{@code null}が指定された場合
     */
    public <T> Out<T> createOut(String name, ExporterDescription exporter) {
        Precondition.checkMustNotBeNull(name, "name"); //$NON-NLS-1$
        Precondition.checkMustNotBeNull(exporter, "exporter"); //$NON-NLS-1$
        if (isValidName(name) == false) {
            throw new IllegalArgumentException(MessageFormat.format(
                    "出力の名前が不正です ({0})",
                    name));
        }
        if (outputs.containsKey(name)) {
            throw new IllegalStateException(MessageFormat.format(
                    "出力の名前が重複しています ({0})",
                    name));
        }
        FlowOut<T> out = new FlowOut<T>(new OutputDescription(name, exporter));
        outputs.put(name, out);
        ports.add(out);
        return out;
    }

    private static final Pattern VALID_NAME = Pattern.compile("[A-Za-z_][0-9A-Za-z_]*");

    /**
     * 指定の名前が入出力の識別子として正しい場合のみ{@code true}を返す。
     * @param name 名前
     * @return 名前が識別子として正しい場合のみ{@code true}、{@code null}や不正な文字列の場合は{@code false}
     */
    public boolean isValidName(String name) {
        if (name == null) {
            return false;
        }
        return VALID_NAME.matcher(name).matches();
    }

    /**
     * これまでに登録した入出力をその順番に返す。
     * <p>
     * 返されるリストに含まれる要素は、必ず{@link FlowIn}{@link FlowOut}のいずれかである。
     * </p>
     * @return これまでに登録した入出力
     */
    public List<Object> getPorts() {
        return ports;
    }

    /**
     * 指定のフロー記述オブジェクトを解釈し、ここまでに作成した入出力を起点とする
     * 演算子グラフを構築して返す。
     * @param description 対象のフロー記述オブジェクト
     * @return 生成した演算子グラフ
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public FlowGraph createFlowGraph(FlowDescription description) {
        Precondition.checkMustNotBeNull(description, "description"); //$NON-NLS-1$
        description.start();
        FlowGraph result = new FlowGraph(
                description.getClass(),
                Lists.from(inputs.values()),
                Lists.from(outputs.values()));
        inputs.clear();
        outputs.clear();
        return result;
    }
}
TOP

Related Classes of com.asakusafw.compiler.flow.FlowDescriptionDriver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.