    001/*
    002 * Copyright (c) 2016 Chris K Wensel <chris@wensel.net>. All Rights Reserved.
    003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved.
    004 *
    005 * Project and contact information: http://www.cascading.org/
    006 *
    007 * This file is part of the Cascading project.
    008 *
    009 * Licensed under the Apache License, Version 2.0 (the "License");
    010 * you may not use this file except in compliance with the License.
    011 * You may obtain a copy of the License at
    012 *
    013 *     http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing, software
    016 * distributed under the License is distributed on an "AS IS" BASIS,
    017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    018 * See the License for the specific language governing permissions and
    019 * limitations under the License.
    020 */
    021
    022package cascading.flow.planner.rule.partitioner;
    023
    024import java.util.ArrayList;
    025import java.util.Arrays;
    026
    027import cascading.flow.planner.iso.ElementAnnotation;
    028import cascading.flow.planner.iso.expression.ExpressionGraph;
    029import cascading.flow.planner.iso.subgraph.GraphPartitioner;
    030import cascading.flow.planner.iso.subgraph.partitioner.ExpressionGraphPartitioner;
    031import cascading.flow.planner.rule.PlanPhase;
    032import cascading.flow.planner.rule.RuleExpression;
    033import cascading.flow.planner.rule.RulePartitioner;
    034import cascading.flow.planner.rule.util.LogLevel;
    035
    036/**
    037 * Class ExpressionRulePartitioner relies on a {@link cascading.flow.planner.rule.RuleExpression} to identify
    038 * sub-graphs as partitions.
    039 */
    040public class ExpressionRulePartitioner extends RulePartitioner
    041  {
    042  Enum[] annotationExcludes = new Enum[ 0 ];
    043
    044  public ExpressionRulePartitioner( PlanPhase phase, RuleExpression ruleExpression )
    045    {
    046    this( null, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    047    }
    048
    049  public ExpressionRulePartitioner( PlanPhase phase, RuleExpression ruleExpression, ElementAnnotation... annotations )
    050    {
    051    this( null, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression(), annotations );
    052    }
    053
    054  public ExpressionRulePartitioner( PlanPhase phase, RuleExpression ruleExpression, Enum... annotationExcludes )
    055    {
    056    this( null, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    057
    058    if( annotationExcludes != null )
    059      this.annotationExcludes = annotationExcludes;
    060    }
    061
    062  public ExpressionRulePartitioner( PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression )
    063    {
    064    this( null, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    065    }
    066
    067  public ExpressionRulePartitioner( PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression, ElementAnnotation... annotations )
    068    {
    069    this( null, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression(), annotations );
    070    }
    071
    072  public ExpressionRulePartitioner( PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression, Enum... annotationExcludes )
    073    {
    074    this( null, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    075
    076    if( annotationExcludes != null )
    077      this.annotationExcludes = annotationExcludes;
    078    }
    079
    080  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, RuleExpression ruleExpression )
    081    {
    082    this( logLevel, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    083    }
    084
    085  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, RuleExpression ruleExpression, ElementAnnotation... annotations )
    086    {
    087    this( logLevel, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression(), annotations );
    088    }
    089
    090  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, RuleExpression ruleExpression, Enum... annotationExcludes )
    091    {
    092    this( logLevel, phase, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    093
    094    if( annotationExcludes != null )
    095      this.annotationExcludes = annotationExcludes;
    096    }
    097
    098  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression )
    099    {
    100    this( logLevel, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    101    }
    102
    103  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression, ElementAnnotation... annotations )
    104    {
    105    this( logLevel, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression(), annotations );
    106    }
    107
    108  public ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, PartitionSource partitionSource, RuleExpression ruleExpression, Enum... annotationExcludes )
    109    {
    110    this( logLevel, phase, partitionSource, ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression() );
    111
    112    if( annotationExcludes != null )
    113      this.annotationExcludes = annotationExcludes;
    114    }
    115
    116  protected ExpressionRulePartitioner( PlanPhase phase, GraphPartitioner graphPartitioner )
    117    {
    118    this.phase = phase;
    119    this.graphPartitioner = graphPartitioner;
    120    }
    121
    122  protected ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, GraphPartitioner graphPartitioner )
    123    {
    124    this.logLevel = logLevel;
    125    this.phase = phase;
    126    this.graphPartitioner = graphPartitioner;
    127    }
    128
    129  private ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, ExpressionGraph contractionGraph, ExpressionGraph expressionGraph, ElementAnnotation... annotations )
    130    {
    131    this.logLevel = logLevel;
    132    this.phase = phase;
    133    this.graphPartitioner = createExpressionGraphPartitioner( contractionGraph, expressionGraph, annotations );
    134    }
    135
    136  private ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase, PartitionSource partitionSource, ExpressionGraph contractionGraph, ExpressionGraph expressionGraph, ElementAnnotation... annotations )
    137    {
    138    this.logLevel = logLevel;
    139    this.phase = phase;
    140    this.partitionSource = partitionSource;
    141    this.graphPartitioner = createExpressionGraphPartitioner( contractionGraph, expressionGraph, annotations );
    142    }
    143
    144  protected ExpressionRulePartitioner( PlanPhase phase )
    145    {
    146    this.phase = phase;
    147    }
    148
    149  protected ExpressionRulePartitioner( LogLevel logLevel, PlanPhase phase )
    150    {
    151    this.logLevel = logLevel;
    152    this.phase = phase;
    153    }
    154
    155  protected ExpressionRulePartitioner()
    156    {
    157    }
    158
    159  protected ExpressionGraphPartitioner createExpressionGraphPartitioner( ExpressionGraph contractionGraph, ExpressionGraph expressionGraph, ElementAnnotation[] annotations )
    160    {
    161    return new ExpressionGraphPartitioner( contractionGraph, expressionGraph, annotations );
    162    }
    163
    164  private ExpressionGraphPartitioner getExpressionGraphPartitioner()
    165    {
    166    return (ExpressionGraphPartitioner) graphPartitioner;
    167    }
    168
    169  protected ExpressionRulePartitioner setPhase( PlanPhase phase )
    170    {
    171    this.phase = phase;
    172
    173    return this;
    174    }
    175
    176  public ExpressionRulePartitioner setRuleExpression( RuleExpression ruleExpression )
    177    {
    178    this.graphPartitioner = createExpressionGraphPartitioner( ruleExpression.getContractionExpression(), ruleExpression.getMatchExpression(), new ElementAnnotation[ 0 ] );
    179
    180    return this;
    181    }
    182
    183  public ExpressionRulePartitioner addAnnotation( ElementAnnotation annotation )
    184    {
    185    ArrayList<ElementAnnotation> elementAnnotations = new ArrayList<>( Arrays.asList( getExpressionGraphPartitioner().getAnnotations() ) );
    186
    187    elementAnnotations.add( annotation );
    188
    189    getExpressionGraphPartitioner().setAnnotations( elementAnnotations.toArray( new ElementAnnotation[ elementAnnotations.size() ] ) );
    190
    191    return this;
    192    }
    193
    194  public RulePartitioner setAnnotations( ElementAnnotation... annotations )
    195    {
    196    getExpressionGraphPartitioner().setAnnotations( annotations );
    197
    198    return this;
    199    }
    200
    201  public void setAnnotationExcludes( Enum... annotationExcludes )
    202    {
    203    if( annotationExcludes != null )
    204      this.annotationExcludes = annotationExcludes;
    205    }
    206
    207  public RulePartitioner addAnnotationExclude( Enum exclude )
    208    {
    209    ArrayList<Enum> exclusions = new ArrayList<>( Arrays.asList( this.annotationExcludes ) );
    210
    211    exclusions.add( exclude );
    212
    213    this.annotationExcludes = exclusions.toArray( new Enum[ exclusions.size() ] );
    214
    215    return this;
    216    }
    217
    218  @Override
    219  public Enum[] getAnnotationExcludes()
    220    {
    221    return annotationExcludes;
    222    }
    223  }