/*
* Copyright (c) 2014 Google, Inc.
*
* Licensed 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 com.google.common.truth;
import com.google.common.annotations.GwtIncompatible;
import org.junit.ComparisonFailure;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Extracted routines that need to be swapped in for GWT, to allow for
* minimal deltas between the GWT and non-GWT version.
*
* @author Christian Gruber (cgruber@google.com)
*/
public final class Platform {
private Platform() {}
/**
* Returns true if the instance is assignable to the type Clazz.
*/
public static boolean isInstanceOfType(Object instance, Class<?> clazz) {
return isInstanceOfTypeJava(instance, clazz);
}
/**
* Returns true if the instance is assignable to the type Clazz (suitable for a JVM
* environment).
*/
@GwtIncompatible("Reflection")
static boolean isInstanceOfTypeJava(Object instance, Class<?> clazz) {
return clazz.isInstance(instance);
}
/**
* Returns true if the instance is assignable to the type Clazz (suitable for a GWT
* environment).
*/
static boolean isInstanceOfTypeGWT(Object instance, Class<?> clazz) {
String className = clazz.getName();
Set<String> types = new LinkedHashSet<String>();
types.add(instance.getClass().getCanonicalName());
addTypeNames(instance.getClass(), types);
for (String type : types) {
if (type.equals(className)) {
return true;
}
}
return false;
}
private static void addInterfaceNames(Class<?>[] interfaces, Set<String> types) {
for (Class<?> interfaze : interfaces) {
types.add(interfaze.getName());
addInterfaceNames(interfaze.getInterfaces(), types);
}
}
private static void addTypeNames(Class<?> clazz, Set<String> types) {
for (Class<?> current = clazz ; current != null ; current = current.getSuperclass()) {
types.add(current.getName());
addInterfaceNames(current.getInterfaces(), types);
}
}
public static final Pattern TYPE_PATTERN = Pattern.compile("(?:[\\w$]+\\.)*([\\w\\.*$]+)");
/**
* Inspired by JavaWriter.
*/
public static String compressType(String type) {
type = typeOnly(type);
StringBuilder sb = new StringBuilder();
Matcher m = TYPE_PATTERN.matcher(type);
int pos = 0;
while (true) {
boolean found = m.find(pos);
// Copy non-matching characters like "<".
int typeStart = found ? m.start() : type.length();
sb.append(type, pos, typeStart);
if (!found) {
break;
}
// Copy a single class name, shortening it if possible.
String name = m.group(0);
name = stripIfInPackage(name, "java.lang.");
name = stripIfInPackage(name, "java.util.");
sb.append(name);
pos = m.end();
}
return sb.toString();
}
private static String typeOnly(String type) {
type = stripIfPrefixed(type, "class ");
type = stripIfPrefixed(type, "interface ");
return type;
}
private static String stripIfPrefixed(String string, String prefix) {
return (string.startsWith(prefix)) ? string.substring(prefix.length()) : string;
}
private static String stripIfInPackage(String type, String packagePrefix) {
if (type.startsWith(packagePrefix)
&& (type.indexOf('.', packagePrefix.length()) == -1)
&& Character.isUpperCase(type.charAt(packagePrefix.length()))) {
return type.substring(packagePrefix.length());
}
return type;
}
public static AssertionError comparisonFailure(String message, String expected, String actual) {
return new ComparisonFailure(message, expected, actual);
}
}