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