001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.functor.adapter;
018
019import org.apache.commons.functor.BinaryProcedure;
020import org.apache.commons.functor.NullaryProcedure;
021import org.apache.commons.lang3.Validate;
022
023/**
024 * Adapts a
025 * {@link BinaryProcedure BinaryProcedure}
026 * to the
027 * {@link NullaryProcedure NullaryProcedure} interface
028 * using a constant left-side argument.
029 *
030 * @version $Revision: 1365377 $ $Date: 2012-07-24 21:59:23 -0300 (Tue, 24 Jul 2012) $
031 */
032public final class FullyBoundNullaryProcedure implements NullaryProcedure {
033    /** The {@link BinaryProcedure BinaryProcedure} I'm wrapping. */
034    private final BinaryProcedure<Object, Object> procedure;
035    /** The left parameter to pass to {@code procedure}. */
036    private final Object left;
037    /** The right parameter to pass to {@code procedure}. */
038    private final Object right;
039
040    /**
041     * Create a new FullyBoundNullaryProcedure instance.
042     * @param <L> left type
043     * @param <R> right type
044     * @param procedure the procedure to adapt
045     * @param left the left argument to use
046     * @param right the right argument to use
047     */
048    @SuppressWarnings("unchecked")
049    public <L, R> FullyBoundNullaryProcedure(BinaryProcedure<? super L, ? super R> procedure, L left, R right) {
050        this.procedure =
051            (BinaryProcedure<Object, Object>) Validate.notNull(procedure,
052                "BinaryProcedure argument was null");
053        this.left = left;
054        this.right = right;
055    }
056
057    /**
058     * {@inheritDoc}
059     */
060    public void run() {
061        procedure.run(left, right);
062    }
063
064    /**
065     * {@inheritDoc}
066     */
067    @Override
068    public boolean equals(Object obj) {
069        if (obj == this) {
070            return true;
071        }
072        if (!(obj instanceof FullyBoundNullaryProcedure)) {
073            return false;
074        }
075        FullyBoundNullaryProcedure that = (FullyBoundNullaryProcedure) obj;
076        return procedure.equals(that.procedure)
077                && (null == left ? null == that.left : left.equals(that.left))
078                && (null == right ? null == that.right : right.equals(that.right));
079    }
080
081    /**
082     * {@inheritDoc}
083     */
084    @Override
085    public int hashCode() {
086        int hash = "FullyBoundNullaryProcedure".hashCode();
087        hash <<= 2;
088        hash ^= procedure.hashCode();
089        hash <<= 2;
090        if (null != left) {
091            hash ^= left.hashCode();
092        }
093        hash <<= 2;
094        if (null != right) {
095            hash ^= right.hashCode();
096        }
097        return hash;
098    }
099
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    public String toString() {
105        return "FullyBoundNullaryProcedure<" + procedure + "(" + left + ", " + right + ")>";
106    }
107
108    /**
109     * Adapt a BinaryNullaryProcedure to the NullaryProcedure interface.
110     * @param <L> left type
111     * @param <R> right type
112     * @param procedure to adapt
113     * @param left left side argument
114     * @param right right side argument
115     * @return FullyBoundNullaryProcedure
116     */
117    public static <L, R> FullyBoundNullaryProcedure bind(
118            BinaryProcedure<? super L, ? super R> procedure, L left, R right) {
119        return null == procedure ? null : new FullyBoundNullaryProcedure(procedure, left, right);
120    }
121
122}