Skip to content

Commit b9fabd3

Browse files
authored
feat(serialization): Allow dynamic models to have non-public default ctors (#41)
1 parent eebccab commit b9fabd3

File tree

4 files changed

+97
-6
lines changed

4 files changed

+97
-6
lines changed

src/main/java/com/ibm/cloud/sdk/core/util/DynamicModelTypeAdapterFactory.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
106106
Constructor<?> ctor = getDefaultCtor(rawType);
107107
if (ctor == null) {
108108
LOGGER.warning("Instance of class " + rawType.getName() + " is a subclass of DynamicModel, but it doesn't "
109-
+ "have a public default constructor. This instance will be ignored by " + this.getClass().getSimpleName());
109+
+ "define a default constructor. This instance will be ignored by " + this.getClass().getSimpleName());
110110
return null;
111111
}
112112

@@ -121,10 +121,13 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
121121
* @return clazz's default ctor
122122
*/
123123
protected Constructor<?> getDefaultCtor(Class<?> clazz) {
124-
Constructor<?>[] allCtors = clazz.getConstructors();
124+
Constructor<?>[] allCtors = clazz.getDeclaredConstructors();
125125
for (int i = 0; i < allCtors.length; i++) {
126126
Constructor<?> ctor = allCtors[i];
127127
if (ctor.getParameterTypes().length == 0) {
128+
if (!ctor.isAccessible()) {
129+
accessor.makeAccessible(ctor);
130+
}
128131
return ctor;
129132
}
130133
}

src/test/java/com/ibm/cloud/sdk/core/test/model/DynamicModelSerializationTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.ibm.cloud.sdk.core.test.model.generated.ModelAPFooNullTypeToken;
2424
import com.ibm.cloud.sdk.core.test.model.generated.ModelAPInteger;
2525
import com.ibm.cloud.sdk.core.test.model.generated.ModelAPObject;
26+
import com.ibm.cloud.sdk.core.test.model.generated.ModelAPProtectedCtor;
2627
import com.ibm.cloud.sdk.core.test.model.generated.ModelAPString;
2728
import com.ibm.cloud.sdk.core.util.GsonSingleton;
2829
import org.testng.annotations.Test;
@@ -130,6 +131,15 @@ private ModelAPString createModelAPString() {
130131
return model;
131132
}
132133

134+
private ModelAPProtectedCtor createModelAPProtectedCtor() {
135+
ModelAPProtectedCtor model = new ModelAPProtectedCtor("x");
136+
model.setProp1("value1");
137+
model.setProp2(Long.valueOf(33));
138+
model.put("baseball", "C");
139+
model.put("football", "LT");
140+
return model;
141+
}
142+
133143
private Foo createFoo(String foo, int bar) {
134144
Foo fooModel = new Foo();
135145
fooModel.setFoo(foo);
@@ -261,6 +271,13 @@ public void testModelAPFooNull() {
261271
assertNull(model);
262272
}
263273

274+
@Test
275+
public void testModelAPProtectedCtor() {
276+
ModelAPProtectedCtor model = createModelAPProtectedCtor();
277+
// model.put("basketball", Integer.valueOf(33));
278+
testSerDeser(model, ModelAPProtectedCtor.class, false);
279+
}
280+
264281
@Test(expectedExceptions = {JsonSyntaxException.class}, expectedExceptionsMessageRegExp="Duplicate key: baseball")
265282
public void testModelAPFooDuplicateKey() {
266283
// Serialize a ModelAPFoo instance

src/test/java/com/ibm/cloud/sdk/core/test/model/generated/ModelAPFooNoCtor.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ public class ModelAPFooNoCtor extends DynamicModel<Foo> {
2525
@SerializedName(value="prop2", alternate={"property2", "p2"})
2626
private Long prop2;
2727

28-
private ModelAPFooNoCtor() {
29-
super(null);
30-
}
31-
3228
public ModelAPFooNoCtor(String x) {
3329
super(new TypeToken<Foo>(){});
3430
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2018 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5+
* the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
package com.ibm.cloud.sdk.core.test.model.generated;
14+
15+
import com.google.gson.annotations.SerializedName;
16+
import com.google.gson.reflect.TypeToken;
17+
import com.ibm.cloud.sdk.core.service.model.DynamicModel;
18+
19+
/**
20+
* Model with additionalProperties set to a string schema.
21+
*/
22+
public class ModelAPProtectedCtor extends DynamicModel<String> {
23+
@SerializedName("prop1")
24+
private String prop1;
25+
@SerializedName("prop2")
26+
private Long prop2;
27+
28+
protected ModelAPProtectedCtor() {
29+
super(new TypeToken<String>(){});
30+
}
31+
32+
public ModelAPProtectedCtor(String x) {
33+
this();
34+
}
35+
36+
/**
37+
* Gets the prop1.
38+
*
39+
* String property.
40+
*
41+
* @return the prop1
42+
*/
43+
public String prop1() {
44+
return this.prop1;
45+
}
46+
47+
/**
48+
* Sets the prop1.
49+
*
50+
* @param prop1 the new prop1
51+
*/
52+
public void setProp1(final String prop1) {
53+
this.prop1 = prop1;
54+
}
55+
56+
/**
57+
* Gets the prop2.
58+
*
59+
* Integer property.
60+
*
61+
* @return the prop2
62+
*/
63+
public Long prop2() {
64+
return this.prop2;
65+
}
66+
67+
/**
68+
* Sets the prop2.
69+
*
70+
* @param prop2 the new prop2
71+
*/
72+
public void setProp2(final long prop2) {
73+
this.prop2 = prop2;
74+
}
75+
}

0 commit comments

Comments
 (0)