001    /*
002     * Copyright (c) 2007-2015 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.text;
022    
023    import java.beans.ConstructorProperties;
024    import java.util.Formatter;
025    
026    import cascading.flow.FlowProcess;
027    import cascading.operation.BaseOperation;
028    import cascading.operation.Function;
029    import cascading.operation.FunctionCall;
030    import cascading.operation.OperationCall;
031    import cascading.tuple.Fields;
032    import cascading.tuple.Tuple;
033    
034    /**
035     * Class FieldFormatter formats the values in a Tuple with a given format and stuffs the result into a new field.
036     * <p/>
037     * This function uses the {@link Formatter} class for formatting the argument tuple values into a new string.
038     */
039    public class FieldFormatter extends BaseOperation<Tuple> implements Function<Tuple>
040      {
041      /** Field FIELD_NAME */
042      public static final String FIELD_NAME = "formatted";
043    
044      /** Field format */
045      private String format = null;
046    
047      /**
048       * Constructor FieldJoiner creates a new FieldFormatter instance using the default field name "formatted".
049       *
050       * @param format of type String
051       */
052      @ConstructorProperties({"format"})
053      public FieldFormatter( String format )
054        {
055        super( new Fields( FIELD_NAME ) );
056        this.format = format;
057        }
058    
059      /**
060       * Constructor FieldJoiner creates a new FieldFormatter instance.
061       *
062       * @param fieldDeclaration of type Fields
063       * @param format           of type String
064       */
065      @ConstructorProperties({"fieldDeclaration", "format"})
066      public FieldFormatter( Fields fieldDeclaration, String format )
067        {
068        super( fieldDeclaration );
069        this.format = format;
070    
071        if( fieldDeclaration.size() != 1 )
072          throw new IllegalArgumentException( "fieldDeclaration may only declare one field name, got " + fieldDeclaration.print() );
073        }
074    
075      /**
076       * Method getFormat returns the format of this FieldFormatter object.
077       *
078       * @return the format (type String) of this FieldFormatter object.
079       */
080      public String getFormat()
081        {
082        return format;
083        }
084    
085      @Override
086      public void prepare( FlowProcess flowProcess, OperationCall<Tuple> operationCall )
087        {
088        operationCall.setContext( Tuple.size( 1 ) );
089        }
090    
091      @Override
092      public void operate( FlowProcess flowProcess, FunctionCall<Tuple> functionCall )
093        {
094        functionCall.getContext().set( 0, functionCall.getArguments().getTuple().format( format ) );
095        functionCall.getOutputCollector().add( functionCall.getContext() );
096        }
097    
098      @Override
099      public boolean equals( Object object )
100        {
101        if( this == object )
102          return true;
103        if( !( object instanceof FieldFormatter ) )
104          return false;
105        if( !super.equals( object ) )
106          return false;
107    
108        FieldFormatter that = (FieldFormatter) object;
109    
110        if( format != null ? !format.equals( that.format ) : that.format != null )
111          return false;
112    
113        return true;
114        }
115    
116      @Override
117      public int hashCode()
118        {
119        int result = super.hashCode();
120        result = 31 * result + ( format != null ? format.hashCode() : 0 );
121        return result;
122        }
123      }