/*******************************************************************************
* Copyright (c) 2011, 2016 itemis AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Wienand (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.common.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Map;
import org.eclipse.gef.common.adapt.AdaptableSupport;
import org.eclipse.gef.common.adapt.AdapterKey;
import org.eclipse.gef.common.adapt.IAdaptable;
import org.junit.Test;
import com.google.common.reflect.TypeToken;
import javafx.beans.property.ReadOnlyMapProperty;
import javafx.collections.ObservableMap;
public class AdaptableSupportTests {
private class AdaptableSupportWrapper implements IAdaptable {
private AdaptableSupport<AdaptableSupportWrapper> ads = new AdaptableSupport<>(
this);
@Override
public ReadOnlyMapProperty<AdapterKey<?>, Object> adaptersProperty() {
return ads.adaptersProperty();
}
protected void clear() {
for (Object adapter : ads.getAdapters().values()) {
ads.unsetAdapter(adapter);
}
}
@Override
public <T> T getAdapter(AdapterKey<T> key) {
return ads.getAdapter(key);
}
@Override
public <T> T getAdapter(Class<T> key) {
return ads.getAdapter(key);
}
@Override
public <T> T getAdapter(TypeToken<T> key) {
return ads.getAdapter(key);
}
@Override
public <T> AdapterKey<T> getAdapterKey(T adapter) {
return ads.getAdapterKey(adapter);
}
@Override
public ObservableMap<AdapterKey<?>, Object> getAdapters() {
return ads.getAdapters();
}
@Override
public <T> Map<AdapterKey<? extends T>, T> getAdapters(
Class<? super T> key) {
return ads.getAdapters(key);
}
@Override
public <T> Map<AdapterKey<? extends T>, T> getAdapters(
TypeToken<? super T> key) {
return ads.getAdapters(key);
}
@Override
public <T> void setAdapter(T adapter) {
ads.setAdapter(adapter);
}
@Override
public <T> void setAdapter(T adapter, String role) {
ads.setAdapter(adapter, role);
}
@Override
public <T> void setAdapter(TypeToken<T> adapterType, T adapter) {
ads.setAdapter(adapterType, adapter);
}
@Override
public <T> void setAdapter(TypeToken<T> adapterType, T adapter,
String role) {
ads.setAdapter(adapterType, adapter, role);
}
@Override
public <T> void unsetAdapter(T adapter) {
ads.unsetAdapter(adapter);
}
}
private class BoundParameterizedType extends ParameterizedType<Object> {
}
private class ParameterizedSubType<T> extends ParameterizedType<T> {
}
private class ParameterizedSuperType<T> extends Object {
}
private class ParameterizedType<T> extends ParameterizedSuperType<T> {
}
private class ParameterType1 extends Object {
}
private class ParameterType2 extends Object {
}
@SuppressWarnings({ "serial", "rawtypes" })
@Test
public void registrationWithAdapterTypeOnly() {
AdaptableSupportWrapper td = new AdaptableSupportWrapper();
ParameterizedSubType<ParameterType1> adapter1 = new ParameterizedSubType<>();
TypeToken<ParameterizedSuperType<ParameterType1>> superSuperType = new TypeToken<ParameterizedSuperType<ParameterType1>>() {
};
TypeToken<ParameterizedType<ParameterType1>> superType = new TypeToken<ParameterizedType<ParameterType1>>() {
};
TypeToken<ParameterizedSubType<ParameterType1>> actualType = new TypeToken<ParameterizedSubType<ParameterType1>>() {
};
// register adapter via actual type should succeed
td.setAdapter(actualType, adapter1);
// should fail (as not matching runtime type)
td.clear();
try {
td.setAdapter(superType, adapter1);
fail("Call succeeded but should have failed");
} catch (Exception e) {
}
// should fail (as not matching runtime type)
td.clear();
try {
td.setAdapter(superSuperType, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
// should fail (as actual parameter type not bound)
td.clear();
try {
td.setAdapter(new TypeToken<ParameterizedType<?>>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
// should fail (as actual parameter type not matching)
td.clear();
try {
td.setAdapter(
new TypeToken<ParameterizedType<? extends ParameterType1>>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
// should fail (as actual parameter type not matching)
td.clear();
try {
td.setAdapter(
new TypeToken<ParameterizedType<? super ParameterType1>>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
// should fail (as raw type is used)
td.clear();
try {
td.setAdapter(new TypeToken<ParameterizedType>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
BoundParameterizedType adapter2 = new BoundParameterizedType();
// should succeed
td.clear();
td.setAdapter(new TypeToken<BoundParameterizedType>() {
}, adapter2);
// should fail (because adapter type is raw super type)
td.clear();
try {
td.setAdapter(new TypeToken<ParameterizedType>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
// should fail (because adapter type is super type)
td.clear();
try {
td.setAdapter(new TypeToken<ParameterizedType<ParameterType1>>() {
}, adapter1);
fail("Call succeeded but should have failed");
} catch (IllegalArgumentException e) {
}
}
@SuppressWarnings({ "serial", "rawtypes" })
@Test
public void retrievalOfMultipleAdapters() {
AdaptableSupportWrapper td = new AdaptableSupportWrapper();
// register adapters
ParameterizedType<ParameterType1> parameterType1 = new ParameterizedType<>();
ParameterizedType<ParameterType2> parameterType2 = new ParameterizedType<>();
td.setAdapter(new TypeToken<ParameterizedType<ParameterType1>>() {
}, parameterType1);
td.setAdapter(new TypeToken<ParameterizedType<ParameterType2>>() {
}, parameterType2);
// check retrieval
assertNotNull(td
.getAdapter(new TypeToken<ParameterizedType<ParameterType1>>() {
}));
assertNotNull(td
.getAdapter(new TypeToken<ParameterizedType<ParameterType2>>() {
}));
// getAdapter(TypeToken) using parameterized type
assertEquals(parameterType1, td
.getAdapter(new TypeToken<ParameterizedType<ParameterType1>>() {
}));
assertEquals(parameterType2, td
.getAdapter(new TypeToken<ParameterizedType<ParameterType2>>() {
}));
// getAdapter(Class) -> no adapter found because of ambiguity
assertNull(td.getAdapter(ParameterizedType.class));
// getAdapters(TypeToken) using parameterized types -> matching adapter
// found
assertEquals(1, td.getAdapters(
new TypeToken<ParameterizedType<ParameterType1>>() {
}).size());
assertEquals(1, td.getAdapters(
new TypeToken<ParameterizedType<ParameterType2>>() {
}).size());
// getAdapters(Class) -> both adapters found, as compatible
assertEquals(2, td.getAdapters(ParameterizedType.class).size());
// getAdapters(TypeToken) using wildcard type -> -> both adapters found,
// as compatible
assertEquals(2, td.getAdapters(new TypeToken<ParameterizedType<?>>() {
}).size());
// getAdapters(TypeToken) using raw type -> -> both adapters found, as
// compatible
assertEquals(2, td.getAdapters(new TypeToken<ParameterizedType>() {
}).size());
}
@SuppressWarnings("serial")
@Test
public void retrievalOfParameterizedType() {
AdaptableSupportWrapper td = new AdaptableSupportWrapper();
ParameterizedSubType<ParameterType1> adapter = new ParameterizedSubType<>();
TypeToken<ParameterizedSuperType<ParameterType1>> superType = new TypeToken<ParameterizedSuperType<ParameterType1>>() {
};
TypeToken<ParameterizedSubType<ParameterType1>> actualType = new TypeToken<ParameterizedSubType<ParameterType1>>() {
};
// register adapter via actual type
td.setAdapter(actualType, adapter);
// retrieve via actual type
assertEquals(adapter, td.getAdapter(actualType));
// retrieve via super type
assertEquals(adapter, td.getAdapter(superType));
// retrieve via wildcard actual type
assertEquals(adapter,
td.getAdapter(new TypeToken<ParameterizedSubType<?>>() {
}));
// retrieve via wildcard super type
assertEquals(adapter,
td.getAdapter(new TypeToken<ParameterizedSuperType<?>>() {
}));
// retrieve via raw actual type
assertEquals(adapter, td.getAdapter(ParameterizedSubType.class));
// retrieve via raw super type
assertEquals(adapter, td.getAdapter(ParameterizedSuperType.class));
}
}