blob: 6f27153221b8cf24007073bba0346970f03ff4e7 [file] [log] [blame]
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package selectionresolution;
import java.util.Arrays;
import java.util.HashSet;
/**
* Representation of an expected result.
*/
public interface Result {
public static final Result ICCE = new Exception(IncompatibleClassChangeError.class);
public static final Result IAE = new Exception(IllegalAccessError.class);
public static final Result NSME = new Exception(NoSuchMethodError.class);
public static final Result AME = new Exception(AbstractMethodError.class);
// Factories
/**
* Create a result that expects the given class.
*/
public static Result is(int id) {
return new Single(id);
}
/**
* Create a result that expects the given classes.
*/
public static Result is(int... multiple) {
assert multiple.length > 0;
if (multiple.length == 1) {
return new Single(multiple[0]);
} else {
return new Any(multiple);
}
}
/**
* Create a result that expects the given exception to be thrown.
*/
public static Result is(Class<? extends Throwable> exType) {
return new Exception(exType);
}
/**
* Create a result that expects the given exception to be thrown.
*/
public static Result is(Throwable ex) {
return Result.is(ex.getClass());
}
public static final Result EMPTY = new Empty();
/**
* Create an empty Result.
*/
public static Result empty() {
return EMPTY;
}
public boolean complyWith(int i);
public boolean complyWith(Throwable e);
public boolean complyWith(Result r);
static class Empty implements Result {
@Override
public boolean complyWith(int i) {
return false;
}
@Override
public boolean complyWith(Throwable e) {
return false;
}
@Override
public boolean complyWith(Result r) {
return false;
}
}
static class Single implements Result {
public int id;
public Single(int id) {
this.id = id;
}
@Override
public boolean complyWith(int i) {
return id == i;
}
@Override
public boolean complyWith(Throwable e) {
return false;
}
@Override
public boolean complyWith(Result r) {
if (r instanceof Single) {
return complyWith(((Single)r).id);
} else if (r instanceof Any) {
return r.complyWith(this);
}
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Single)) return false;
Single single = (Single) o;
return (id == single.id);
}
@Override
public int hashCode() {
return id;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Result=Single{");
sb.append("id=").append(id);
sb.append('}');
return sb.toString();
}
}
static class Any implements Result {
public int[] ids;
public Any(int[] ids) {
this.ids = ids;
}
@Override
public boolean complyWith(int i) {
return Arrays.stream(ids)
.anyMatch(j -> j == i);
}
@Override
public boolean complyWith(Throwable e) {
return false;
}
@Override
public boolean complyWith(Result r) {
if (r instanceof Single) {
return complyWith(((Single)r).id);
}
if (r instanceof Any) {
return Arrays.equals(ids, ((Any) r).ids);
}
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Any any = (Any) o;
return Arrays.equals(ids, any.ids);
}
@Override
public int hashCode() {
return Arrays.hashCode(ids);
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Result=Any{");
sb.append("ids=");
if (ids == null) sb.append("null");
else {
sb.append('[');
for (int i = 0; i < ids.length; ++i)
sb.append(i == 0 ? "" : ", ").append(ids[i]);
sb.append(']');
}
sb.append('}');
return sb.toString();
}
}
static class Exception implements Result {
public Class<? extends Throwable> exc;
public Exception(Class<? extends Throwable> e) {
this.exc = e;
}
@Override
public boolean complyWith(int i) {
return false;
}
@Override
public boolean complyWith(Throwable e) {
return exc.isAssignableFrom(e.getClass());
}
@Override
public boolean complyWith(Result r) {
if (r instanceof Exception) {
return exc.isAssignableFrom(((Exception) r).exc);
}
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Exception)) return false;
Exception exception = (Exception) o;
return exc.equals(exception.exc);
}
@Override
public int hashCode() {
return exc.hashCode();
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Result=Exception{");
sb.append("exc=").append(exc);
sb.append('}');
return sb.toString();
}
}
}