/** * 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.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Represents shuffle key properties. */ public class ShuffleKey { static final Pattern ORDER_PATTERN = Pattern.compile( "(\\S+)(\\s+(ASC|DESC))?", //$NON-NLS-1$ Pattern.CASE_INSENSITIVE); private final List<String> groupProperties; private final List<Order> orderings; /** * Creates a new instance. * @param groupProperties grouping properties * @param orderings ordering information * @throws IllegalArgumentException if some parameters are {@code null} */ public ShuffleKey(List<String> groupProperties, List<Order> orderings) { if (groupProperties == null) { throw new IllegalArgumentException("groupProperties must not be null"); //$NON-NLS-1$ } if (orderings == null) { throw new IllegalArgumentException("orderings must not be null"); //$NON-NLS-1$ } this.groupProperties = Collections.unmodifiableList(new ArrayList<>(groupProperties)); this.orderings = Collections.unmodifiableList(new ArrayList<>(orderings)); } /** * Returns the grouping properties. * @return the grouping properties */ public List<String> getGroupProperties() { return groupProperties; } /** * Returns ordering information. * @return ordering information */ public List<Order> getOrderings() { return orderings; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + groupProperties.hashCode(); result = prime * result + orderings.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } ShuffleKey other = (ShuffleKey) obj; if (!groupProperties.equals(other.groupProperties)) { return false; } if (!orderings.equals(other.orderings)) { return false; } return true; } /** * Represents ordering information. */ public static class Order { private final String property; private final Direction direction; /** * Creates a new instance. * @param property the property name * @param direction the ordering direction * @throws IllegalArgumentException if some parameters are {@code null} */ public Order(String property, Direction direction) { if (property == null) { throw new IllegalArgumentException("property must not be null"); //$NON-NLS-1$ } if (direction == null) { throw new IllegalArgumentException("direction must not be null"); //$NON-NLS-1$ } this.property = property; this.direction = direction; } /** * Returns the property name of ordering key. * @return the property name */ public String getProperty() { return property; } /** * Returns the ordering direction. * @return the ordering direction */ public Direction getDirection() { return direction; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + direction.hashCode(); result = prime * result + property.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Order other = (Order) obj; if (direction != other.direction) { return false; } if (!property.equals(other.property)) { return false; } return true; } /** * Parses a string form of {@code <property-name> <direction>} (as same as {@link Order#toString()}), * and returns the corresponded {@link Order} object. * @param string a string of {@link Order#toString()} * @return the corresponded object, or {@code null} if the string is not valid form * @throws IllegalArgumentException if the parameter is {@code null} */ public static Order parse(String string) { if (string == null) { throw new IllegalArgumentException("string must not be null"); //$NON-NLS-1$ } Matcher matcher = ORDER_PATTERN.matcher(string.trim()); if (matcher.matches() == false) { return null; } String property = matcher.group(1); String directionString = matcher.group(3); if (directionString == null) { return new Order(property, Direction.ASC); } directionString = directionString.trim(); if (directionString.equalsIgnoreCase(Direction.ASC.name())) { return new Order(property, Direction.ASC); } if (directionString.equalsIgnoreCase(Direction.DESC.name())) { return new Order(property, Direction.DESC); } return null; } @Override public String toString() { return MessageFormat.format( "{0} {1}", //$NON-NLS-1$ getProperty(), getDirection().name()); } } /** * Represents ordering direction. */ public enum Direction { /** * Ascendant. */ ASC, /** * Descendant. */ DESC, } }