    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;
    022
    023import cascading.flow.planner.PlannerContext;
    024import cascading.flow.planner.graph.ElementGraph;
    025import cascading.flow.planner.iso.transformer.ContractedTransformer;
    026import cascading.flow.planner.iso.transformer.GraphTransformer;
    027import cascading.flow.planner.iso.transformer.RecursiveGraphTransformer;
    028import cascading.flow.planner.iso.transformer.SubGraphTransformer;
    029import cascading.flow.planner.iso.transformer.Transformed;
    030
    031/**
    032 * The RuleTransformer class is responsible for transforming an element graph into a new graph.
    033 */
    034public class RuleTransformer extends GraphTransformer<ElementGraph, ElementGraph> implements Rule
    035  {
    036  private final PlanPhase phase;
    037  protected final RuleExpression ruleExpression;
    038  protected final ContractedTransformer contractedTransformer;
    039  protected final SubGraphTransformer subGraphTransformer;
    040
    041  protected RecursiveGraphTransformer<ElementGraph> graphTransformer;
    042
    043  public RuleTransformer( PlanPhase phase, RuleExpression ruleExpression )
    044    {
    045    this.phase = phase;
    046    this.ruleExpression = ruleExpression;
    047
    048    if( ruleExpression.getContractionExpression() != null )
    049      contractedTransformer = new ContractedTransformer( ruleExpression.getContractionExpression() );
    050    else
    051      contractedTransformer = null;
    052
    053    if( ruleExpression.getContractedMatchExpression() != null )
    054      {
    055      if( contractedTransformer == null )
    056        throw new IllegalArgumentException( "must have contracted expression if given contracted match expression" );
    057
    058      subGraphTransformer = new SubGraphTransformer( contractedTransformer, ruleExpression.getContractedMatchExpression() );
    059      }
    060    else
    061      {
    062      subGraphTransformer = null;
    063      }
    064    }
    065
    066  @Override
    067  public PlanPhase getRulePhase()
    068    {
    069    return phase;
    070    }
    071
    072  @Override
    073  public String getRuleName()
    074    {
    075    return getClass().getSimpleName().replaceAll( "^(.*)[]A-Z][a-z]*Rule$", "$1" );
    076    }
    077
    078  @Override
    079  public Transformed<ElementGraph> transform( PlannerContext plannerContext, ElementGraph rootGraph )
    080    {
    081    Transformed<ElementGraph> result = new Transformed<>( plannerContext, this, rootGraph );
    082
    083    ElementGraph graphCopy = rootGraph.copyElementGraph();
    084
    085    Transformed<ElementGraph> transformed = graphTransformer.transform( plannerContext, graphCopy );
    086
    087    result.addChildTransform( transformed );
    088
    089    if( transformed.getEndGraph() != null && !rootGraph.equals( transformed.getEndGraph() ) )
    090      result.setEndGraph( transformed.getEndGraph() );
    091
    092    return result;
    093    }
    094
    095  @Override
    096  public String toString()
    097    {
    098    return getRuleName();
    099    }
    100  }