    001    /*
    002     * Copyright (c) 2007-2014 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
    021    package cascading.operation.regex;
    022
    023    import java.beans.ConstructorProperties;
    024    import java.util.regex.Pattern;
    025
    026    import cascading.flow.FlowProcess;
    027    import cascading.operation.Function;
    028    import cascading.operation.FunctionCall;
    029    import cascading.operation.OperationCall;
    030    import cascading.tuple.Fields;
    031    import cascading.tuple.Tuple;
    032    import cascading.util.Pair;
    033
    034    /**
    035     * Class RegexGenerator will emit a new Tuple for every split on the incoming argument value delimited by the given patternString.
    036     * <p/>
    037     * This could be used to break a document into single word tuples for later processing for a word count.
    038     */
    039    public class RegexSplitGenerator extends RegexOperation<Pair<Pattern, Tuple>> implements Function<Pair<Pattern, Tuple>>
    040      {
    041      /**
    042       * Constructor RegexGenerator creates a new RegexGenerator instance.
    043       *
    044       * @param patternString of type String
    045       */
    046      @ConstructorProperties({"patternString"})
    047      public RegexSplitGenerator( String patternString )
    048        {
    049        super( 1, Fields.size( 1 ), patternString );
    050        }
    051
    052      /**
    053       * Constructor RegexGenerator creates a new RegexGenerator instance.
    054       *
    055       * @param fieldDeclaration of type Fields
    056       * @param patternString    of type String
    057       */
    058      @ConstructorProperties({"fieldDeclaration", "patternString"})
    059      public RegexSplitGenerator( Fields fieldDeclaration, String patternString )
    060        {
    061        super( 1, fieldDeclaration, patternString );
    062
    063        if( fieldDeclaration.size() != 1 )
    064          throw new IllegalArgumentException( "fieldDeclaration may only declare one field, was " + fieldDeclaration.print() );
    065        }
    066
    067      @Override
    068      public void prepare( FlowProcess flowProcess, OperationCall<Pair<Pattern, Tuple>> operationCall )
    069        {
    070        operationCall.setContext( new Pair<Pattern, Tuple>( getPattern(), Tuple.size( 1 ) ) );
    071        }
    072
    073      @Override
    074      public void operate( FlowProcess flowProcess, FunctionCall<Pair<Pattern, Tuple>> functionCall )
    075        {
    076        String value = functionCall.getArguments().getString( 0 );
    077
    078        if( value == null )
    079          value = "";
    080
    081        String[] split = functionCall.getContext().getLhs().split( value );
    082
    083        for( String string : split )
    084          {
    085          functionCall.getContext().getRhs().set( 0, string );
    086          functionCall.getOutputCollector().add( functionCall.getContext().getRhs() );
    087          }
    088        }
    089      }