Add models for Apache Commons tuples

This commit is contained in:
Chris Smowton
2021-04-26 15:39:09 +01:00
parent 73fa680224
commit 472a2a64dd
9 changed files with 1311 additions and 0 deletions

View File

@@ -789,3 +789,62 @@ private class ApacheToStringBuilderModel extends SummaryModelCsv {
]
}
}
/**
* Value-propagating models for `Pair`, `ImmutablePair` and `MutablePair`.
*/
private class ApachePairModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.tuple;Pair;false;getKey;;;Field org.apache.commons.lang3.tuple.ImmutablePair.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getValue;;;Field org.apache.commons.lang3.tuple.ImmutablePair.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getKey;;;Field org.apache.commons.lang3.tuple.MutablePair.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getValue;;;Field org.apache.commons.lang3.tuple.MutablePair.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.ImmutablePair.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.ImmutablePair.right of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;getLeft;;;Field org.apache.commons.lang3.tuple.ImmutablePair.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;getRight;;;Field org.apache.commons.lang3.tuple.ImmutablePair.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;right;;;Argument[0];Field org.apache.commons.lang3.tuple.ImmutablePair.right of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;left;;;Argument[0];Field org.apache.commons.lang3.tuple.ImmutablePair.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.ImmutablePair.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.ImmutablePair.right of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;getLeft;;;Field org.apache.commons.lang3.tuple.MutablePair.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;getRight;;;Field org.apache.commons.lang3.tuple.MutablePair.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;setLeft;;;Argument[0];Field org.apache.commons.lang3.tuple.MutablePair.left of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;setRight;;;Argument[0];Field org.apache.commons.lang3.tuple.MutablePair.right of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;setValue;;;Argument[0];Field org.apache.commons.lang3.tuple.MutablePair.right of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.MutablePair.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.MutablePair.right of ReturnValue;value"
]
}
}
/**
* Value-propagating models for `Triple`, `ImmutableTriple` and `MutableTriple`.
*/
private class ApacheTripleModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.ImmutableTriple.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.ImmutableTriple.middle of ReturnValue;value",
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field org.apache.commons.lang3.tuple.ImmutableTriple.right of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getLeft;;;Field org.apache.commons.lang3.tuple.ImmutableTriple.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getMiddle;;;Field org.apache.commons.lang3.tuple.ImmutableTriple.middle of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getRight;;;Field org.apache.commons.lang3.tuple.ImmutableTriple.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.ImmutableTriple.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.ImmutableTriple.middle of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field org.apache.commons.lang3.tuple.ImmutableTriple.right of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getLeft;;;Field org.apache.commons.lang3.tuple.MutableTriple.left of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getMiddle;;;Field org.apache.commons.lang3.tuple.MutableTriple.middle of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getRight;;;Field org.apache.commons.lang3.tuple.MutableTriple.right of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setLeft;;;Argument[0];Field org.apache.commons.lang3.tuple.MutableTriple.left of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setMiddle;;;Argument[0];Field org.apache.commons.lang3.tuple.MutableTriple.middle of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setRight;;;Argument[0];Field org.apache.commons.lang3.tuple.MutableTriple.right of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field org.apache.commons.lang3.tuple.MutableTriple.left of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field org.apache.commons.lang3.tuple.MutableTriple.middle of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field org.apache.commons.lang3.tuple.MutableTriple.right of ReturnValue;value"
]
}
}

View File

@@ -0,0 +1,112 @@
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.MutablePair;
class PairTest {
String taint() { return "tainted"; }
private static class IntSource {
static int taint() { return 0; }
}
void sink(Object o) {}
void test() throws Exception {
ImmutablePair<String, String> taintedLeft = ImmutablePair.of(taint(), "clean-right");
ImmutablePair<String, String> taintedRight = ImmutablePair.of("clean-left", taint());
Pair<String, String> taintedLeft2_ = ImmutablePair.left(taint());
ImmutablePair<String, String> taintedLeft2 = (ImmutablePair)taintedLeft2_;
Pair<String, String> taintedRight2_ = ImmutablePair.right(taint());
ImmutablePair<String, String> taintedRight2 = (ImmutablePair)taintedRight2_;
// Check flow through ImmutablePairs:
sink(taintedLeft.getLeft()); // $hasValueFlow
sink(taintedLeft.getRight());
sink(taintedLeft.getKey()); // $hasValueFlow
sink(taintedLeft.getValue());
sink(taintedLeft.left); // $hasValueFlow
sink(taintedLeft.right);
sink(taintedRight.getLeft());
sink(taintedRight.getRight()); // $hasValueFlow
sink(taintedRight.getKey());
sink(taintedRight.getValue()); // $hasValueFlow
sink(taintedRight.left);
sink(taintedRight.right); // $hasValueFlow
sink(taintedLeft2.getLeft()); // $hasValueFlow
sink(taintedLeft2.getRight());
sink(taintedLeft2.getKey()); // $hasValueFlow
sink(taintedLeft2.getValue());
sink(taintedLeft2.left); // $hasValueFlow
sink(taintedLeft2.right);
sink(taintedRight2.getLeft());
sink(taintedRight2.getRight()); // $hasValueFlow
sink(taintedRight2.getKey());
sink(taintedRight2.getValue()); // $hasValueFlow
sink(taintedRight2.left);
sink(taintedRight2.right); // $hasValueFlow
// Check flow also works via an alias of type Pair:
sink(taintedLeft2_.getLeft()); // $hasValueFlow
sink(taintedLeft2_.getRight());
sink(taintedLeft2_.getKey()); // $hasValueFlow
sink(taintedLeft2_.getValue());
sink(taintedRight2_.getLeft());
sink(taintedRight2_.getRight()); // $hasValueFlow
sink(taintedRight2_.getKey());
sink(taintedRight2_.getValue()); // $hasValueFlow
// Check flow through MutablePairs:
MutablePair<String, String> taintedLeftMutable = MutablePair.of(taint(), "clean-right");
MutablePair<String, String> taintedRightMutable = MutablePair.of("clean-left", taint());
MutablePair<String, String> setTaintLeft = MutablePair.of("clean-left", "clean-right");
setTaintLeft.setLeft(taint());
MutablePair<String, String> setTaintRight = MutablePair.of("clean-left", "clean-right");
setTaintRight.setRight(taint());
MutablePair<String, String> setTaintValue = MutablePair.of("clean-left", "clean-right");
setTaintValue.setValue(taint());
sink(taintedLeftMutable.getLeft()); // $hasValueFlow
sink(taintedLeftMutable.getRight());
sink(taintedLeftMutable.getKey()); // $hasValueFlow
sink(taintedLeftMutable.getValue());
sink(taintedLeftMutable.left); // $hasValueFlow
sink(taintedLeftMutable.right);
sink(taintedRightMutable.getLeft());
sink(taintedRightMutable.getRight()); // $hasValueFlow
sink(taintedRightMutable.getKey());
sink(taintedRightMutable.getValue()); // $hasValueFlow
sink(taintedRightMutable.left);
sink(taintedRightMutable.right); // $hasValueFlow
sink(setTaintLeft.getLeft()); // $hasValueFlow
sink(setTaintLeft.getRight());
sink(setTaintLeft.getKey()); // $hasValueFlow
sink(setTaintLeft.getValue());
sink(setTaintLeft.left); // $hasValueFlow
sink(setTaintLeft.right);
sink(setTaintRight.getLeft());
sink(setTaintRight.getRight()); // $hasValueFlow
sink(setTaintRight.getKey());
sink(setTaintRight.getValue()); // $hasValueFlow
sink(setTaintRight.left);
sink(setTaintRight.right); // $hasValueFlow
sink(setTaintValue.getLeft());
sink(setTaintValue.getRight()); // $hasValueFlow
sink(setTaintValue.getKey());
sink(setTaintValue.getValue()); // $hasValueFlow
sink(setTaintValue.left);
sink(setTaintValue.right); // $hasValueFlow
// Check flow also works via an alias of type Pair:
Pair<String, String> taintedLeftMutableAlias = taintedLeftMutable;
Pair<String, String> taintedRightMutableAlias = taintedRightMutable;
sink(taintedLeftMutableAlias.getLeft()); // $hasValueFlow
sink(taintedLeftMutableAlias.getRight());
sink(taintedLeftMutableAlias.getKey()); // $hasValueFlow
sink(taintedLeftMutableAlias.getValue());
sink(taintedRightMutableAlias.getLeft());
sink(taintedRightMutableAlias.getRight()); // $hasValueFlow
sink(taintedRightMutableAlias.getKey());
sink(taintedRightMutableAlias.getValue()); // $hasValueFlow
}
}

View File

@@ -0,0 +1,130 @@
import org.apache.commons.lang3.tuple.Triple;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.MutableTriple;
class TripleTest {
String taint() { return "tainted"; }
private static class IntSource {
static int taint() { return 0; }
}
void sink(Object o) {}
void test() throws Exception {
ImmutableTriple<String, String, String> taintedLeft = ImmutableTriple.of(taint(), "clean-middle", "clean-right");
ImmutableTriple<String, String, String> taintedMiddle = ImmutableTriple.of("clean-left", taint(), "clean-right");
ImmutableTriple<String, String, String> taintedRight = ImmutableTriple.of("clean-left", "clean-middle", taint());
// Check flow through ImmutableTriples:
sink(taintedLeft.getLeft()); // $hasValueFlow
sink(taintedLeft.getMiddle());
sink(taintedLeft.getRight());
sink(taintedLeft.left); // $hasValueFlow
sink(taintedLeft.middle);
sink(taintedLeft.right);
sink(taintedMiddle.getLeft());
sink(taintedMiddle.getMiddle()); // $hasValueFlow
sink(taintedMiddle.getRight());
sink(taintedMiddle.left);
sink(taintedMiddle.middle); // $hasValueFlow
sink(taintedMiddle.right);
sink(taintedRight.getLeft());
sink(taintedRight.getMiddle());
sink(taintedRight.getRight()); // $hasValueFlow
sink(taintedRight.left);
sink(taintedRight.middle);
sink(taintedRight.right); // $hasValueFlow
Triple<String, String, String> taintedLeft2 = taintedLeft;
Triple<String, String, String> taintedMiddle2 = taintedMiddle;
Triple<String, String, String> taintedRight2 = taintedRight;
// Check flow also works via an alias of type Triple:
sink(taintedLeft2.getLeft()); // $hasValueFlow
sink(taintedLeft2.getMiddle());
sink(taintedLeft2.getRight());
sink(taintedMiddle2.getLeft());
sink(taintedMiddle2.getMiddle()); // $hasValueFlow
sink(taintedMiddle2.getRight());
sink(taintedRight2.getLeft());
sink(taintedRight2.getMiddle());
sink(taintedRight2.getRight()); // $hasValueFlow
MutableTriple<String, String, String> mutableTaintedLeft = MutableTriple.of(taint(), "clean-middle", "clean-right");
MutableTriple<String, String, String> mutableTaintedMiddle = MutableTriple.of("clean-left", taint(), "clean-right");
MutableTriple<String, String, String> mutableTaintedRight = MutableTriple.of("clean-left", "clean-middle", taint());
MutableTriple<String, String, String> setTaintedLeft = MutableTriple.of("clean-left", "clean-middle", "clean-right");
setTaintedLeft.setLeft(taint());
MutableTriple<String, String, String> setTaintedMiddle = MutableTriple.of("clean-left", "clean-middle", "clean-right");
setTaintedMiddle.setMiddle(taint());
MutableTriple<String, String, String> setTaintedRight = MutableTriple.of("clean-left", "clean-middle", "clean-right");
setTaintedRight.setRight(taint());
// Check flow through MutableTriples:
sink(mutableTaintedLeft.getLeft()); // $hasValueFlow
sink(mutableTaintedLeft.getMiddle());
sink(mutableTaintedLeft.getRight());
sink(mutableTaintedLeft.left); // $hasValueFlow
sink(mutableTaintedLeft.middle);
sink(mutableTaintedLeft.right);
sink(mutableTaintedMiddle.getLeft());
sink(mutableTaintedMiddle.getMiddle()); // $hasValueFlow
sink(mutableTaintedMiddle.getRight());
sink(mutableTaintedMiddle.left);
sink(mutableTaintedMiddle.middle); // $hasValueFlow
sink(mutableTaintedMiddle.right);
sink(mutableTaintedRight.getLeft());
sink(mutableTaintedRight.getMiddle());
sink(mutableTaintedRight.getRight()); // $hasValueFlow
sink(mutableTaintedRight.left);
sink(mutableTaintedRight.middle);
sink(mutableTaintedRight.right); // $hasValueFlow
sink(setTaintedLeft.getLeft()); // $hasValueFlow
sink(setTaintedLeft.getMiddle());
sink(setTaintedLeft.getRight());
sink(setTaintedLeft.left); // $hasValueFlow
sink(setTaintedLeft.middle);
sink(setTaintedLeft.right);
sink(setTaintedMiddle.getLeft());
sink(setTaintedMiddle.getMiddle()); // $hasValueFlow
sink(setTaintedMiddle.getRight());
sink(setTaintedMiddle.left);
sink(setTaintedMiddle.middle); // $hasValueFlow
sink(setTaintedMiddle.right);
sink(setTaintedRight.getLeft());
sink(setTaintedRight.getMiddle());
sink(setTaintedRight.getRight()); // $hasValueFlow
sink(setTaintedRight.left);
sink(setTaintedRight.middle);
sink(setTaintedRight.right); // $hasValueFlow
Triple<String, String, String> mutableTaintedLeft2 = mutableTaintedLeft;
Triple<String, String, String> mutableTaintedMiddle2 = mutableTaintedMiddle;
Triple<String, String, String> mutableTaintedRight2 = mutableTaintedRight;
Triple<String, String, String> setTaintedLeft2 = setTaintedLeft;
Triple<String, String, String> setTaintedMiddle2 = setTaintedMiddle;
Triple<String, String, String> setTaintedRight2 = setTaintedRight;
// Check flow also works via an alias of type Triple:
sink(mutableTaintedLeft2.getLeft()); // $hasValueFlow
sink(mutableTaintedLeft2.getMiddle());
sink(mutableTaintedLeft2.getRight());
sink(mutableTaintedMiddle2.getLeft());
sink(mutableTaintedMiddle2.getMiddle()); // $hasValueFlow
sink(mutableTaintedMiddle2.getRight());
sink(mutableTaintedRight2.getLeft());
sink(mutableTaintedRight2.getMiddle());
sink(mutableTaintedRight2.getRight()); // $hasValueFlow
sink(setTaintedLeft2.getLeft()); // $hasValueFlow
sink(setTaintedLeft2.getMiddle());
sink(setTaintedLeft2.getRight());
sink(setTaintedMiddle2.getLeft());
sink(setTaintedMiddle2.getMiddle()); // $hasValueFlow
sink(setTaintedMiddle2.getRight());
sink(setTaintedRight2.getLeft());
sink(setTaintedRight2.getMiddle());
sink(setTaintedRight2.getRight()); // $hasValueFlow
}
}

View File

@@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
import java.util.Map;
/**
* <p>An immutable pair consisting of two {@code Object} elements.</p>
*
* <p>Although the implementation is immutable, there is no restriction on the objects
* that may be stored. If mutable objects are stored in the pair, then the pair
* itself effectively becomes mutable. The class is also {@code final}, so a subclass
* can not add undesirable behavior.</p>
*
* <p>#ThreadSafe# if both paired objects are thread-safe</p>
*
* @param <L> the left element type
* @param <R> the right element type
*
* @since 3.0
*/
public final class ImmutablePair<L, R> extends Pair<L, R> {
/**
* An empty array.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final ImmutablePair<?, ?>[] EMPTY_ARRAY = null;
/**
* An immutable pair of nulls.
*/
// This is not defined with generics to avoid warnings in call sites.
@SuppressWarnings("rawtypes")
private static final ImmutablePair NULL = null;
/** Serialization version */
private static final long serialVersionUID = 4954918890077093841L;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, R> ImmutablePair<L, R>[] emptyArray() {
return null;
}
/**
* <p>Creates an immutable pair of two objects inferring the generic types.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param left the left element, may be null
* @return a pair formed from the two parameters, not null
* @since 3.11
*/
public static <L, R> Pair<L, R> left(final L left) {
return null;
}
/**
* Returns an immutable pair of nulls.
*
* @param <L> the left element of this pair. Value is {@code null}.
* @param <R> the right element of this pair. Value is {@code null}.
* @return an immutable pair of nulls.
* @since 3.6
*/
public static <L, R> ImmutablePair<L, R> nullPair() {
return null;
}
/**
* <p>Creates an immutable pair of two objects inferring the generic types.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param left the left element, may be null
* @param right the right element, may be null
* @return a pair formed from the two parameters, not null
*/
public static <L, R> ImmutablePair<L, R> of(final L left, final R right) {
return null;
}
/**
* <p>Creates an immutable pair from an existing pair.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param pair the existing pair.
* @return a pair formed from the two parameters, not null
* @since 3.10
*/
public static <L, R> ImmutablePair<L, R> of(final Map.Entry<L, R> pair) {
return null;
}
/**
* <p>Creates an immutable pair of two objects inferring the generic types.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param right the right element, may be null
* @return a pair formed from the two parameters, not null
* @since 3.11
*/
public static <L, R> Pair<L, R> right(final R right) {
return null;
}
/** Left object */
public final L left;
/** Right object */
public final R right;
/**
* Create a new pair instance.
*
* @param left the left value, may be null
* @param right the right value, may be null
*/
public ImmutablePair(final L left, final R right) {
this.left = null;
this.right = null;
}
/**
* {@inheritDoc}
*/
@Override
public L getLeft() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public R getRight() {
return null;
}
/**
* <p>Throws {@code UnsupportedOperationException}.</p>
*
* <p>This pair is immutable, so this operation is not supported.</p>
*
* @param value the value to set
* @return never
* @throws UnsupportedOperationException as this operation is not supported
*/
@Override
public R setValue(final R value) {
return null;
}
}

View File

@@ -0,0 +1,137 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
/**
* <p>An immutable triple consisting of three {@code Object} elements.</p>
*
* <p>Although the implementation is immutable, there is no restriction on the objects
* that may be stored. If mutable objects are stored in the triple, then the triple
* itself effectively becomes mutable. The class is also {@code final}, so a subclass
* can not add undesirable behavior.</p>
*
* <p>#ThreadSafe# if all three objects are thread-safe</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
*
* @since 3.2
*/
public final class ImmutableTriple<L, M, R> extends Triple<L, M, R> {
/**
* An empty array.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final ImmutableTriple<?, ?, ?>[] EMPTY_ARRAY = null;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, M, R> ImmutableTriple<L, M, R>[] emptyArray() {
return null;
}
/**
* Returns an immutable triple of nulls.
*
* @param <L> the left element of this triple. Value is {@code null}.
* @param <M> the middle element of this triple. Value is {@code null}.
* @param <R> the right element of this triple. Value is {@code null}.
* @return an immutable triple of nulls.
* @since 3.6
*/
public static <L, M, R> ImmutableTriple<L, M, R> nullTriple() {
return null;
}
/**
* <p>Obtains an immutable triple of three objects inferring the generic types.</p>
*
* <p>This factory allows the triple to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @param left the left element, may be null
* @param middle the middle element, may be null
* @param right the right element, may be null
* @return a triple formed from the three parameters, not null
*/
public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
return null;
}
/** Left object */
public final L left;
/** Middle object */
public final M middle;
/** Right object */
public final R right;
/**
* Create a new triple instance.
*
* @param left the left value, may be null
* @param middle the middle value, may be null
* @param right the right value, may be null
*/
public ImmutableTriple(final L left, final M middle, final R right) {
this.left = null;
this.middle = null;
this.right = null;
}
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public L getLeft() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public M getMiddle() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public R getRight() {
return null;
}
}

View File

@@ -0,0 +1,158 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
import java.util.Map;
/**
* <p>A mutable pair consisting of two {@code Object} elements.</p>
*
* <p>Not #ThreadSafe#</p>
*
* @param <L> the left element type
* @param <R> the right element type
*
* @since 3.0
*/
public class MutablePair<L, R> extends Pair<L, R> {
/**
* An empty array.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final MutablePair<?, ?>[] EMPTY_ARRAY = null;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, R> MutablePair<L, R>[] emptyArray() {
return null;
}
/**
* <p>Creates a mutable pair of two objects inferring the generic types.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param left the left element, may be null
* @param right the right element, may be null
* @return a pair formed from the two parameters, not null
*/
public static <L, R> MutablePair<L, R> of(final L left, final R right) {
return null;
}
/**
* <p>Creates a mutable pair from an existing pair.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param pair the existing pair.
* @return a pair formed from the two parameters, not null
*/
public static <L, R> MutablePair<L, R> of(final Map.Entry<L, R> pair) {
return null;
}
/** Left object */
public L left;
/** Right object */
public R right;
/**
* Create a new pair instance of two nulls.
*/
public MutablePair() {
}
/**
* Create a new pair instance.
*
* @param left the left value, may be null
* @param right the right value, may be null
*/
public MutablePair(final L left, final R right) {
this.left = null;
this.right = null;
}
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public L getLeft() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public R getRight() {
return null;
}
/**
* Sets the left element of the pair.
*
* @param left the new value of the left element, may be null
*/
public void setLeft(final L left) {
}
/**
* Sets the right element of the pair.
*
* @param right the new value of the right element, may be null
*/
public void setRight(final R right) {
}
/**
* Sets the {@code Map.Entry} value.
* This sets the right element of the pair.
*
* @param value the right value to set, not null
* @return the old value for the right element
*/
@Override
public R setValue(final R value) {
return null;
}
}

View File

@@ -0,0 +1,152 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
/**
* <p>A mutable triple consisting of three {@code Object} elements.</p>
*
* <p>Not #ThreadSafe#</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
*
* @since 3.2
*/
public class MutableTriple<L, M, R> extends Triple<L, M, R> {
/**
* The empty array singleton.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final MutableTriple<?, ?, ?>[] EMPTY_ARRAY = null;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, M, R> MutableTriple<L, M, R>[] emptyArray() {
return null;
}
/**
* <p>Obtains a mutable triple of three objects inferring the generic types.</p>
*
* <p>This factory allows the triple to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @param left the left element, may be null
* @param middle the middle element, may be null
* @param right the right element, may be null
* @return a triple formed from the three parameters, not null
*/
public static <L, M, R> MutableTriple<L, M, R> of(final L left, final M middle, final R right) {
return null;
}
/** Left object */
public L left;
/** Middle object */
public M middle;
/** Right object */
public R right;
/**
* Create a new triple instance of three nulls.
*/
public MutableTriple() {
}
/**
* Create a new triple instance.
*
* @param left the left value, may be null
* @param middle the middle value, may be null
* @param right the right value, may be null
*/
public MutableTriple(final L left, final M middle, final R right) {
this.left = null;
this.middle = null;
this.right = null;
}
//-----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public L getLeft() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public M getMiddle() {
return null;
}
/**
* {@inheritDoc}
*/
@Override
public R getRight() {
return null;
}
/**
* Sets the left element of the triple.
*
* @param left the new value of the left element, may be null
*/
public void setLeft(final L left) {
}
/**
* Sets the middle element of the triple.
*
* @param middle the new value of the middle element, may be null
*/
public void setMiddle(final M middle) {
}
/**
* Sets the right element of the triple.
*
* @param right the new value of the right element, may be null
*/
public void setRight(final R right) {
}
}

View File

@@ -0,0 +1,204 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
import java.io.Serializable;
import java.util.Map;
/**
* <p>A pair consisting of two elements.</p>
*
* <p>This class is an abstract implementation defining the basic API.
* It refers to the elements as 'left' and 'right'. It also implements the
* {@code Map.Entry} interface where the key is 'left' and the value is 'right'.</p>
*
* <p>Subclass implementations may be mutable or immutable.
* However, there is no restriction on the type of the stored objects that may be stored.
* If mutable objects are stored in the pair, then the pair itself effectively becomes mutable.</p>
*
* @param <L> the left element type
* @param <R> the right element type
*
* @since 3.0
*/
public abstract class Pair<L, R> implements Map.Entry<L, R>, Comparable<Pair<L, R>>, Serializable {
/** Serialization version */
private static final long serialVersionUID = 4954918890077093841L;
/**
* An empty array.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final Pair<?, ?>[] EMPTY_ARRAY = null;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, R> Pair<L, R>[] emptyArray() {
return null;
}
/**
* <p>Creates an immutable pair of two objects inferring the generic types.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param left the left element, may be null
* @param right the right element, may be null
* @return a pair formed from the two parameters, not null
*/
public static <L, R> Pair<L, R> of(final L left, final R right) {
return null;
}
/**
* <p>Creates an immutable pair from an existing pair.</p>
*
* <p>This factory allows the pair to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <R> the right element type
* @param pair the existing pair.
* @return a pair formed from the two parameters, not null
* @since 3.10
*/
public static <L, R> Pair<L, R> of(final Map.Entry<L, R> pair) {
return null;
}
//-----------------------------------------------------------------------
/**
* <p>Compares the pair based on the left element followed by the right element.
* The types must be {@code Comparable}.</p>
*
* @param other the other pair, not null
* @return negative if this is less, zero if equal, positive if greater
*/
@Override
public int compareTo(final Pair<L, R> other) {
return 0;
}
/**
* <p>Compares this pair to another based on the two elements.</p>
*
* @param obj the object to compare to, null returns false
* @return true if the elements of the pair are equal
*/
@Override
public boolean equals(final Object obj) {
return false;
}
/**
* <p>Gets the key from this pair.</p>
*
* <p>This method implements the {@code Map.Entry} interface returning the
* left element as the key.</p>
*
* @return the left element as the key, may be null
*/
@Override
public final L getKey() {
return null;
}
//-----------------------------------------------------------------------
/**
* <p>Gets the left element from this pair.</p>
*
* <p>When treated as a key-value pair, this is the key.</p>
*
* @return the left element, may be null
*/
public abstract L getLeft();
/**
* <p>Gets the right element from this pair.</p>
*
* <p>When treated as a key-value pair, this is the value.</p>
*
* @return the right element, may be null
*/
public abstract R getRight();
/**
* <p>Gets the value from this pair.</p>
*
* <p>This method implements the {@code Map.Entry} interface returning the
* right element as the value.</p>
*
* @return the right element as the value, may be null
*/
@Override
public R getValue() {
return null;
}
/**
* <p>Returns a suitable hash code.
* The hash code follows the definition in {@code Map.Entry}.</p>
*
* @return the hash code
*/
@Override
public int hashCode() {
return 0;
}
/**
* <p>Returns a String representation of this pair using the format {@code ($left,$right)}.</p>
*
* @return a string describing this object, not null
*/
@Override
public String toString() {
return "";
}
/**
* <p>Formats the receiver using the given format.</p>
*
* <p>This uses {@link java.util.Formattable} to perform the formatting. Two variables may
* be used to embed the left and right elements. Use {@code %1$s} for the left
* element (key) and {@code %2$s} for the right element (value).
* The default format used by {@code toString()} is {@code (%1$s,%2$s)}.</p>
*
* @param format the format string, optionally containing {@code %1$s} and {@code %2$s}, not null
* @return the formatted string, not null
*/
public String toString(final String format) {
return "";
}
}

View File

@@ -0,0 +1,164 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.tuple;
import java.io.Serializable;
/**
* <p>A triple consisting of three elements.</p>
*
* <p>This class is an abstract implementation defining the basic API.
* It refers to the elements as 'left', 'middle' and 'right'.</p>
*
* <p>Subclass implementations may be mutable or immutable.
* However, there is no restriction on the type of the stored objects that may be stored.
* If mutable objects are stored in the triple, then the triple itself effectively becomes mutable.</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
*
* @since 3.2
*/
public abstract class Triple<L, M, R> implements Comparable<Triple<L, M, R>>, Serializable {
/**
* An empty array.
* <p>
* Consider using {@link #emptyArray()} to avoid generics warnings.
* </p>
*
* @since 3.10.
*/
public static final Triple<?, ?, ?>[] EMPTY_ARRAY = null;
/**
* Returns the empty array singleton that can be assigned without compiler warning.
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @return the empty array singleton that can be assigned without compiler warning.
*
* @since 3.10.
*/
@SuppressWarnings("unchecked")
public static <L, M, R> Triple<L, M, R>[] emptyArray() {
return null;
}
/**
* <p>Obtains an immutable triple of three objects inferring the generic types.</p>
*
* <p>This factory allows the triple to be created using inference to
* obtain the generic types.</p>
*
* @param <L> the left element type
* @param <M> the middle element type
* @param <R> the right element type
* @param left the left element, may be null
* @param middle the middle element, may be null
* @param right the right element, may be null
* @return a triple formed from the three parameters, not null
*/
public static <L, M, R> Triple<L, M, R> of(final L left, final M middle, final R right) {
return null;
}
//-----------------------------------------------------------------------
/**
* <p>Compares the triple based on the left element, followed by the middle element,
* finally the right element.
* The types must be {@code Comparable}.</p>
*
* @param other the other triple, not null
* @return negative if this is less, zero if equal, positive if greater
*/
@Override
public int compareTo(final Triple<L, M, R> other) {
return 0;
}
/**
* <p>Compares this triple to another based on the three elements.</p>
*
* @param obj the object to compare to, null returns false
* @return true if the elements of the triple are equal
*/
@Override
public boolean equals(final Object obj) {
return false;
}
//-----------------------------------------------------------------------
/**
* <p>Gets the left element from this triple.</p>
*
* @return the left element, may be null
*/
public abstract L getLeft();
/**
* <p>Gets the middle element from this triple.</p>
*
* @return the middle element, may be null
*/
public abstract M getMiddle();
/**
* <p>Gets the right element from this triple.</p>
*
* @return the right element, may be null
*/
public abstract R getRight();
/**
* <p>Returns a suitable hash code.</p>
*
* @return the hash code
*/
@Override
public int hashCode() {
return 0;
}
/**
* <p>Returns a String representation of this triple using the format {@code ($left,$middle,$right)}.</p>
*
* @return a string describing this object, not null
*/
@Override
public String toString() {
return "";
}
/**
* <p>Formats the receiver using the given format.</p>
*
* <p>This uses {@link java.util.Formattable} to perform the formatting. Three variables may
* be used to embed the left and right elements. Use {@code %1$s} for the left
* element, {@code %2$s} for the middle and {@code %3$s} for the right element.
* The default format used by {@code toString()} is {@code (%1$s,%2$s,%3$s)}.</p>
*
* @param format the format string, optionally containing {@code %1$s}, {@code %2$s} and {@code %3$s}, not null
* @return the formatted string, not null
*/
public String toString(final String format) {
return "";
}
}