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.iso.expression;
023
024import cascading.flow.planner.Scope;
025
026/**
027 * If ScopeExpression is the only edge, the {@link ScopeExpression.Applies} enum will apply,
028 * otherwise the number of edges on the target graph must match the number of edges in the expression.
029 */
030public abstract class ScopeExpression implements Expression<Scope>
031  {
032  /**
033   * Where this expression applies between ANY edge between two nodes.
034   */
035  public static final PathScopeExpression ANY = new PathScopeExpression( Applies.Any );
036  /**
037   * Where this expression applies between ALL edges between two nodes.
038   */
039  public static final PathScopeExpression ALL = new PathScopeExpression( Applies.All );
040  public static final PathScopeExpression EACH = new PathScopeExpression( Applies.Each ); // unsupported
041
042  /**
043   * Match the edge, but do not capture it. Only works if the edge matched in the contracted graph is exactly
044   * present in the original graph. If the edge is a contraction of a more complex path, the edges/path won't be
045   * discarded.
046   */
047  public static final PathScopeExpression NO_CAPTURE = new PathScopeExpression( false, Applies.All );
048
049  public enum Applies
050    {
051      /**
052       * At least one edge
053       */
054      Any,
055
056      /**
057       * All edges
058       */
059      All,
060
061      /**
062       * Each edge - unsupported
063       */
064      Each
065    }
066
067  protected boolean capture = true;
068  protected Applies applies = Applies.Any;
069
070  protected ScopeExpression()
071    {
072    }
073
074  protected ScopeExpression( Applies applies )
075    {
076    this.applies = applies;
077    }
078
079  public ScopeExpression( boolean capture, Applies applies )
080    {
081    this.capture = capture;
082    this.applies = applies;
083
084    if( capture == false && applies != Applies.All )
085      throw new IllegalArgumentException( "applies must be ALL if capture is false" );
086    }
087
088  public boolean isCapture()
089    {
090    return capture;
091    }
092
093  /**
094   * This match must apply to all the edges between the two candidate nodes for the match to be true.
095   */
096  public boolean appliesToAllPaths()
097    {
098    return applies == Applies.All;
099    }
100
101  /**
102   * This match must apply to at least one edge between the two candidate nodes for the match to be true.
103   * <p>
104   * The first to apply is captured.
105   */
106  public boolean appliesToAnyPath()
107    {
108    return applies == Applies.Any;
109    }
110
111  /**
112   * This match is applied to each edge, at least one edge between the two candidate nodes must apply for the match
113   * to be true.
114   * <p>
115   * Each edge that applies is captured.
116   */
117  public boolean appliesToEachPath()
118    {
119    return applies == Applies.Each;
120    }
121
122  /**
123   * True if there is at least one edge between the candidate nodes.
124   */
125  public boolean acceptsAll()
126    {
127    return appliesToAllPaths();
128    }
129
130  public Applies getApplies()
131    {
132    return applies;
133    }
134
135  @Override
136  public String toString()
137    {
138    final StringBuilder sb = new StringBuilder( "ScopeExpression{" );
139    sb.append( "capture=" ).append( capture );
140    sb.append( ", applies=" ).append( applies );
141    sb.append( '}' );
142    return sb.toString();
143    }
144  }