/** * Copyright 2011-2017 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.vocabulary.flow.graph; import java.lang.reflect.Type; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * A description of I/O port of flow elements. * @since 0.1.0 * @version 0.9.1 */ public class FlowElementPortDescription implements FlowElementAttributeProvider { private final String name; private final Type dataType; private final PortDirection direction; private final ShuffleKey shuffleKey; private final Map<Class<? extends FlowElementAttribute>, FlowElementAttribute> attributes; /** * Creates a new instance. * @param name the port name * @param dataType the data type of the port * @param direction the port direction * @throws IllegalArgumentException if some parameters are {@code null} */ public FlowElementPortDescription(String name, Type dataType, PortDirection direction) { if (name == null) { throw new IllegalArgumentException("name must not be null"); //$NON-NLS-1$ } if (dataType == null) { throw new IllegalArgumentException("dataType must not be null"); //$NON-NLS-1$ } if (direction == null) { throw new IllegalArgumentException("direction must not be null"); //$NON-NLS-1$ } this.name = name; this.dataType = dataType; this.direction = direction; this.shuffleKey = null; this.attributes = Collections.emptyMap(); } /** * Creates a new instance. * @param name the port name * @param dataType the data type of the port * @param shuffleKey information of the shuffle operation * @throws IllegalArgumentException if some parameters are {@code null} */ public FlowElementPortDescription(String name, Type dataType, ShuffleKey shuffleKey) { if (name == null) { throw new IllegalArgumentException("name must not be null"); //$NON-NLS-1$ } if (dataType == null) { throw new IllegalArgumentException("dataType must not be null"); //$NON-NLS-1$ } if (shuffleKey == null) { throw new IllegalArgumentException("shuffleKey must not be null"); //$NON-NLS-1$ } this.name = name; this.dataType = dataType; this.direction = PortDirection.INPUT; this.shuffleKey = shuffleKey; this.attributes = Collections.emptyMap(); } /** * Creates a new instance. * @param name the port name * @param dataType the data type of the port * @param direction the port direction * @param shuffleKey the shuffle key (nullable) * @param attributes the attributes * @throws IllegalArgumentException if some parameters are {@code null} * @since 0.9.1 */ public FlowElementPortDescription( String name, Type dataType, PortDirection direction, ShuffleKey shuffleKey, FlowElementAttribute...attributes) { this(name, dataType, direction, shuffleKey, Arrays.asList(attributes)); } /** * Creates a new instance. * @param name the port name * @param dataType the data type of the port * @param direction the port direction * @param shuffleKey the shuffle key (nullable) * @param attributes the attributes * @throws IllegalArgumentException if some parameters are {@code null} * @since 0.9.1 */ public FlowElementPortDescription( String name, Type dataType, PortDirection direction, ShuffleKey shuffleKey, List<? extends FlowElementAttribute> attributes) { Objects.requireNonNull(name); Objects.requireNonNull(dataType); Objects.requireNonNull(direction); Objects.requireNonNull(attributes); this.name = name; this.dataType = dataType; this.direction = direction; this.shuffleKey = shuffleKey; Map<Class<? extends FlowElementAttribute>, FlowElementAttribute> map = new LinkedHashMap<>(); for (FlowElementAttribute attr : attributes) { map.put(attr.getDeclaringClass(), attr); } this.attributes = Collections.unmodifiableMap(map); } /** * Returns the port name. * @return the port name. */ public String getName() { return name; } /** * Return the data type of this port. * @return the data type */ public Type getDataType() { return dataType; } /** * Returns the port direction. * @return the port direction */ public PortDirection getDirection() { return direction; } /** * Returns information of the shuffle operation which will performs on this port. * @return shuffle operation information, or {@code null} if this port does not support shuffle operations */ public ShuffleKey getShuffleKey() { return shuffleKey; } @Override public Set<? extends Class<? extends FlowElementAttribute>> getAttributeTypes() { return attributes.keySet(); } @Override public <T extends FlowElementAttribute> T getAttribute(Class<T> attributeClass) { if (attributeClass == null) { throw new IllegalArgumentException("attributeClass must not be null"); //$NON-NLS-1$ } return attributeClass.cast(attributes.get(attributeClass)); } @Override public String toString() { if (direction == PortDirection.INPUT) { return MessageFormat.format( "Input({0}):{1}", //$NON-NLS-1$ getName(), getDataType()); } else { return MessageFormat.format( "Output({0}):{1}", //$NON-NLS-1$ getName(), getDataType()); } } }