001/*
002 * Copyright (c) 2007-2017 Xplenty, 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.iso.transformer;
022
023import java.util.Set;
024
025import cascading.flow.FlowElement;
026import cascading.flow.planner.graph.ElementGraph;
027import cascading.flow.planner.graph.ElementGraphs;
028import cascading.flow.planner.iso.expression.ElementCapture;
029import cascading.flow.planner.iso.expression.ExpressionGraph;
030import cascading.flow.planner.iso.finder.Match;
031
032/**
033 * GraphTransformer that uses the supplied factory to generate the replacement FlowElement.
034 * <p>
035 * Note: This only works if exactly one FlowElement is being replaced.
036 */
037public class ReplaceGraphFactoryBasedTransformer extends MutateGraphTransformer
038  {
039  private final String factoryName;
040
041  public ReplaceGraphFactoryBasedTransformer( ExpressionGraph filter, String factoryName )
042    {
043    super( null, filter );
044    this.factoryName = factoryName;
045
046    if( factoryName == null )
047      throw new IllegalArgumentException( "factoryName may not be null" );
048    }
049
050  public ReplaceGraphFactoryBasedTransformer( GraphTransformer graphTransformer, ExpressionGraph filter, String factoryName )
051    {
052    super( graphTransformer, filter );
053    this.factoryName = factoryName;
054
055    if( factoryName == null )
056      throw new IllegalArgumentException( "factoryName may not be null" );
057    }
058
059  @Override
060  protected boolean transformGraphInPlaceUsing( Transformed<ElementGraph> transformed, ElementGraph graph, Match match )
061    {
062    ElementFactory elementFactory = transformed.getPlannerContext().getElementFactoryFor( factoryName );
063
064    if( elementFactory == null )
065      return false;
066
067    Set<FlowElement> captured = match.getCapturedElements( ElementCapture.Primary );
068
069    if( captured.isEmpty() )
070      return false;
071    else if( captured.size() != 1 )
072      throw new IllegalStateException( "expected one, but found multiple flow elements in the match expression: " + captured );
073
074    FlowElement replace = captured.iterator().next();
075    FlowElement replaceWith = elementFactory.create( graph, replace );
076    ElementGraphs.replaceElementWith( graph, replace, replaceWith );
077
078    return true;
079    }
080  }