Skip to content

Commit 460715b

Browse files
committed
breaking: Name are composed by a Type and a String
Before the Name was a couple (Class, String), from now on it's a couple (Type, String). The string stay the same, but the Class becomes a Type. Like this we will have a better granularity in order to inject parameterized types. This commit is breaking because the Name class was having a public constructor with a class, and the class have been changed to a Type. WIP: Should we really have a public constructor ?! Personally I think that only private constructors and public static factories should be enough. If you want to build a name with a type, there is multiple solutions. If you want to use a simple generic type (only one depth of generic) like `SomeGeneric<SomeType>`, the easiest way is to use this signature: ```java Name.of(aStringName, SomeGeneric.class, SomeType.class) ``` This method is using the `Types.newParameterizedType` static factory, which is an easy way to build parameterized types. An equivalent technique would be to use something like this: ```java Name.of(Types.newParameterizedType(SomeGeneric.class, SomeType.class), aStringName) ``` (It will be almost equivalent, as the first way will be a little bit more efficient, as the raw type will not be calculated, it is already given in parameter: `SomeGeneric.class`) If you need to build a complex generic type, like `One<Two<Three, Four<Five>>>`, the easiest way will be to use the abstract class `TypeReference` like this: ```java Name.of(new TypeReference<One<Two<Three, Four<Five>>>() {}, aStringName) ```
1 parent 88e1be3 commit 460715b

File tree

4 files changed

+98
-26
lines changed

4 files changed

+98
-26
lines changed

restx-common/src/main/java/restx/common/MoreObjects.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package restx.common;
22

3+
import java.lang.reflect.ParameterizedType;
4+
import java.lang.reflect.Type;
5+
36
/**
47
* Date: 29/11/13
58
* Time: 11:13
@@ -12,6 +15,24 @@ public static String toString(Class clazz) {
1215
return clazz.getName() + "[" + toString(clazz.getClassLoader()) + "]";
1316
}
1417

18+
public static String toString(Type type) {
19+
if (type == null) {
20+
return "null";
21+
}
22+
String typeString;
23+
/*
24+
in jse8 another case should be done, using type.getTypeName() if
25+
type is an instanceof ParameterizedType
26+
*/
27+
if (type instanceof Class) {
28+
typeString = ((Class) type).getName();
29+
} else {
30+
typeString = String.valueOf(type);
31+
}
32+
33+
return typeString + "[" + toString(Types.getRawType(type).getClassLoader()) + "]";
34+
}
35+
1536
public static String toString(ClassLoader classLoader) {
1637
if (classLoader == null) {
1738
return "";
Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,90 @@
11
package restx.factory;
22

3-
import restx.common.MoreObjects;
4-
53
import static com.google.common.base.Preconditions.checkNotNull;
64

5+
6+
import java.lang.reflect.Type;
7+
import restx.common.MoreObjects;
8+
import restx.common.TypeReference;
9+
import restx.common.Types;
10+
711
/**
812
* User: xavierhanin
913
* Date: 1/31/13
1014
* Time: 5:40 PM
1115
*/
1216
public final class Name<T> {
1317
private final String name;
14-
private final Class<T> clazz;
18+
private final Type type;
19+
private final Class<T> rawType;
1520

1621
public static <T> Name<T> of(Class<T> clazz, String name) {
17-
return new Name<>(clazz, name);
22+
return new Name<>(clazz, clazz, name);
1823
}
1924

2025
public static <T> Name<T> of(Class<T> clazz) {
21-
return new Name<>(clazz, clazz.getSimpleName());
26+
return new Name<>(clazz, clazz, clazz.getSimpleName());
2227
}
2328

24-
public Name(Class<T> clazz, String name) {
29+
public static <T> Name<T> of(Type type, String name) {
30+
return new Name<>(type, name);
31+
}
32+
33+
@SuppressWarnings("unchecked")
34+
public static <T> Name<T> of(Type type) {
35+
Class<T> rawType = (Class<T>) Types.getRawType(type);
36+
return new Name<>(type, rawType, rawType.getSimpleName());
37+
}
38+
39+
@SuppressWarnings("unchecked")
40+
public static <T> Name<T> of(String name, Class<?> rawType, Type... arguments) {
41+
return (Name<T>) new Name<>(Types.newParameterizedType(rawType, arguments), rawType, name);
42+
}
43+
44+
public static <T> Name<T> of(TypeReference<T> typeReference, String name) {
45+
return new Name<>(checkNotNull(typeReference).getType(), name);
46+
}
47+
48+
@SuppressWarnings("unchecked")
49+
public Name(Type type, String name) {
50+
this(type, (Class<T>) Types.getRawType(type), name);
51+
}
52+
53+
private Name(Type type, Class<T> rawType, String name) {
2554
this.name = checkNotNull(name);
26-
this.clazz = checkNotNull(clazz);
55+
this.type = checkNotNull(type);
56+
this.rawType = checkNotNull(rawType);
2757
}
2858

2959
public String getSimpleName() {
30-
String simpleName = clazz.getSimpleName();
60+
String simpleName = String.valueOf(type);
3161
if (!simpleName.equalsIgnoreCase(name)) {
3262
simpleName = name + "[" + simpleName + "]";
3363
}
3464
return simpleName;
3565
}
3666

3767
public String asId() {
38-
return "[" + clazz.getName() + "]" + name;
68+
return "[" + String.valueOf(type) + "]" + name;
3969
}
4070

4171
public String getName() {
4272
return name;
4373
}
4474

75+
public Type getType() {
76+
return type;
77+
}
78+
4579
public Class<T> getClazz() {
46-
return clazz;
47-
}
80+
return rawType;
81+
}
4882

4983
@Override
5084
public String toString() {
5185
return "Name{" +
5286
"name='" + name + '\'' +
53-
", clazz=" + MoreObjects.toString(clazz) +
87+
", type=" + MoreObjects.toString(type) +
5488
'}';
5589
}
5690

@@ -61,7 +95,8 @@ public boolean equals(Object o) {
6195

6296
Name name1 = (Name) o;
6397

64-
if (!clazz.equals(name1.clazz)) return false;
98+
if (!rawType.equals(name1.rawType)) return false;
99+
if (!type.equals(name1.type)) return false;
65100
if (!name.equals(name1.name)) return false;
66101

67102
return true;
@@ -70,7 +105,8 @@ public boolean equals(Object o) {
70105
@Override
71106
public int hashCode() {
72107
int result = name.hashCode();
73-
result = 31 * result + clazz.hashCode();
108+
result = 31 * result + rawType.hashCode();
109+
result = 31 * result + type.hashCode();
74110
return result;
75111
}
76112
}

restx-factory/src/main/java/restx/factory/NamedComponent.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package restx.factory;
22

3+
import static com.google.common.base.Preconditions.checkNotNull;
4+
5+
36
import com.google.common.base.Function;
47

5-
import static com.google.common.base.Preconditions.checkNotNull;
8+
import java.lang.reflect.Type;
69

710
/**
811
* User: xavierhanin
@@ -29,13 +32,23 @@ public Name<T> apply(NamedComponent<T> namedComponent) {
2932
}
3033

3134
public static <T> NamedComponent<T> of(Class<T> clazz, String name, T component) {
32-
return new NamedComponent<>(new Name<>(clazz, name), component);
35+
return new NamedComponent<>(Name.of(clazz, name), component);
3336
}
3437

3538
public static <T> NamedComponent<T> of(Class<T> clazz, String name, int priority, T component) {
36-
return new NamedComponent<>(new Name<>(clazz, name), priority, component);
39+
return new NamedComponent<>(Name.of(clazz, name), priority, component);
3740
}
3841

42+
@SuppressWarnings("unchecked")
43+
public static <T> NamedComponent<T> of(Type type, String name, T component) {
44+
return new NamedComponent<>((Name<T>) Name.of(type, name), component);
45+
}
46+
47+
@SuppressWarnings("unchecked")
48+
public static <T> NamedComponent<T> of(Type type, String name, int priority, T component) {
49+
return new NamedComponent<>((Name<T>) Name.of(type, name), priority, component);
50+
}
51+
3952
private final Name<T> name;
4053
private final int priority;
4154
private final T component;

restx-factory/src/test/java/restx/factory/FactoryTest.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package restx.factory;
22

3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.fail;
5+
import static restx.factory.Factory.LocalMachines.threadLocal;
6+
7+
38
import com.google.common.base.Optional;
49
import com.google.common.collect.ImmutableMap;
510
import org.junit.After;
611
import org.junit.Test;
712

813
import java.util.Set;
914

10-
import static org.assertj.core.api.Assertions.*;
11-
import static restx.factory.Factory.LocalMachines.threadLocal;
12-
1315
/**
1416
* User: xavierhanin
1517
* Date: 1/31/13
@@ -179,12 +181,12 @@ public void should_fail_with_missing_deps() throws Exception {
179181
assertThat(e)
180182
.hasMessageStartingWith(
181183
"\n" +
182-
" QueryByName{name=Name{name='test', clazz=java.lang.String[]}}\n" +
183-
" | \\__=> Name{name='test', clazz=java.lang.String[]}\n" +
184+
" QueryByName{name=Name{name='test', type=class java.lang.String[]}}\n" +
185+
" | \\__=> Name{name='test', type=class java.lang.String[]}\n" +
184186
" |\n" +
185-
" +-> QueryByName{name=Name{name='missing', clazz=java.lang.String[]}}\n" +
187+
" +-> QueryByName{name=Name{name='missing', type=class java.lang.String[]}}\n" +
186188
" |\n" +
187-
" +--: Name{name='missing', clazz=java.lang.String[]} can't be satisfied")
189+
" +--: Name{name='missing', type=class java.lang.String[]} can't be satisfied")
188190
;
189191
}
190192
}
@@ -217,9 +219,9 @@ public void should_find_one_when_multiple_available_fail() throws Exception {
217219
" Please select which one you want with a more specific query,\n" +
218220
" or by deactivating one of the available components.\n" +
219221
" Available components:\n" +
220-
" - NamedComponent{name=Name{name='test', clazz=java.lang.String[]}, priority=0, component=value1}\n" +
222+
" - NamedComponent{name=Name{name='test', type=class java.lang.String[]}, priority=0, component=value1}\n" +
221223
" [Activation key: 'restx.activation::java.lang.String::test']\n" +
222-
" - NamedComponent{name=Name{name='test2', clazz=java.lang.String[]}, priority=0, component=value1}\n" +
224+
" - NamedComponent{name=Name{name='test2', type=class java.lang.String[]}, priority=0, component=value1}\n" +
223225
" [Activation key: 'restx.activation::java.lang.String::test2']\n")
224226
;
225227
}

0 commit comments

Comments
 (0)