Skip to content

Commit 2cf0102

Browse files
author
Sakai Developer
committed
fix commons and json encoding issues
1 parent e133972 commit 2cf0102

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

entitybroker/rest/src/java/org/sakaiproject/entitybroker/rest/EntityEncodingManager.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public class EntityEncodingManager {
124124

125125
private static final ObjectMapper JSON_MAPPER = MapperFactory.jsonBuilder()
126126
.ignoreUnknownProperties()
127+
.registerJdk8Module()
127128
.registerJavaTimeModule()
128129
.disableDateTimestamps()
129130
.disableFailOnEmptyBeans()
@@ -474,6 +475,11 @@ public Object internalInputTranslator(EntityReference ref, String format, InputS
474475
*/
475476
public void internalOutputFormatter(EntityReference ref, String format, List<EntityData> entities, Map<String, Object> params, OutputStream output, EntityView view) {
476477
if (format == null) { format = Outputable.HTML; }
478+
String originalFormat = format;
479+
format = format.trim();
480+
if (!format.equals(originalFormat)) {
481+
log.debug("Trimmed format '{}' -> '{}' for ref {}", originalFormat, format, ref);
482+
}
477483

478484
// check the format to see if we can handle it
479485
if (! contains(HANDLED_OUTPUT_FORMATS, format)) {
@@ -608,6 +614,11 @@ public String encodeEntity(String prefix, String format, EntityData entityData,
608614
if (prefix == null || format == null) {
609615
throw new IllegalArgumentException("prefix and format must not be null");
610616
}
617+
String originalFormat = format;
618+
format = format.trim();
619+
if (!format.equals(originalFormat)) {
620+
log.debug("Trimmed encodeEntity format '{}' -> '{}' for prefix {}", originalFormat, format, prefix);
621+
}
611622
if (entityData == null && ! Formats.FORM.equals(format)) {
612623
throw new IllegalArgumentException("entityData to encode must not be null for prefix ("+prefix+") and format ("+format+")");
613624
}
@@ -840,15 +851,31 @@ public String encodeEntity(String prefix, String format, EntityData entityData,
840851
}
841852
}
842853
// do the encoding
854+
String encodingName = prefix;
855+
if ((beanEncodedDirectly || dataOnly) && (Formats.JSON.equals(format) || Formats.JSONP.equals(format))) {
856+
encodingName = null;
857+
}
843858
try {
844-
String encodingName = prefix;
845-
if ((beanEncodedDirectly || dataOnly) && (Formats.JSON.equals(format) || Formats.JSONP.equals(format))) {
846-
encodingName = null;
847-
}
848859
encoded = encodeData(toEncode, format, encodingName, entityProps);
849-
} catch (IllegalArgumentException e) {
850-
// no transcoder so just toString this and dump it out
851-
encoded = prefix + " : " + entityData;
860+
} catch (RuntimeException e) {
861+
log.warn("encodeEntity fallback for prefix={} format={} dataOnly={} beanEncodedDirectly={} entityClass={}",
862+
prefix, format, dataOnly, beanEncodedDirectly, toEncode != null ? toEncode.getClass() : null, e);
863+
if (Formats.JSON.equals(format) || Formats.JSONP.equals(format)) {
864+
try {
865+
Object envelope = mergeProperties(toEncode, entityProps);
866+
if (encodingName != null && !encodingName.isEmpty()) {
867+
LinkedHashMap<String, Object> wrapper = new LinkedHashMap<String, Object>();
868+
wrapper.put(encodingName, envelope);
869+
envelope = wrapper;
870+
}
871+
encoded = JSON_PRETTY_WRITER.writeValueAsString(envelope);
872+
} catch (JsonProcessingException jpe) {
873+
throw new EntityEncodingException("Failure encoding data (" + toEncode + ") of type ("
874+
+ toEncode.getClass() + ")", prefix, jpe);
875+
}
876+
} else {
877+
throw e;
878+
}
852879
}
853880
}
854881
return encoded;
@@ -983,13 +1010,18 @@ private Object convertValueForSerialization(Object value, int currentDepth, int
9831010
}
9841011
return converted;
9851012
} else if (isBeanClass(value.getClass())) {
986-
Map<String, Object> beanValues = getObjectValues(value);
987-
Map<String, Object> converted = new LinkedHashMap<String, Object>(beanValues.size());
988-
for (Entry<String, Object> entry : beanValues.entrySet()) {
989-
converted.put(entry.getKey(),
990-
convertValueForSerialization(entry.getValue(), currentDepth + 1, maxDepth, visited));
1013+
try {
1014+
Map<String, Object> beanValues = getObjectValues(value);
1015+
Map<String, Object> converted = new LinkedHashMap<String, Object>(beanValues.size());
1016+
for (Entry<String, Object> entry : beanValues.entrySet()) {
1017+
converted.put(entry.getKey(),
1018+
convertValueForSerialization(entry.getValue(), currentDepth + 1, maxDepth, visited));
1019+
}
1020+
return converted;
1021+
} catch (RuntimeException ex) {
1022+
log.debug("Bean conversion failed for {}, deferring to serializer: {}", value.getClass(), ex.toString());
1023+
return value; // let Jackson handle it directly
9911024
}
992-
return converted;
9931025
} else {
9941026
return summarizeValue(value);
9951027
}

entitybroker/utils/src/java/org/sakaiproject/entitybroker/util/devhelper/AbstractDeveloperHelperService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ private interface EntityCodec {
407407

408408
private static final ObjectMapper JSON_MAPPER = MapperFactory.jsonBuilder()
409409
.ignoreUnknownProperties()
410+
.registerJdk8Module()
410411
.excludeNulls()
411412
.registerJavaTimeModule()
412413
.disableDateTimestamps()

kernel/api/src/main/java/org/sakaiproject/serialization/MapperFactory.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
2727
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
2828
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
29+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
2930

3031
import javax.xml.stream.XMLInputFactory;
3132

@@ -50,6 +51,7 @@ private MapperFactory() {
5051
*/
5152
public static ObjectMapper createDefaultJsonMapper() {
5253
return jsonBuilder()
54+
.registerJdk8Module()
5355
.registerJavaTimeModule()
5456
.ignoreUnknownProperties()
5557
.excludeNulls()
@@ -161,6 +163,16 @@ public JsonMapperBuilder registerJavaTimeModule() {
161163
return this;
162164
}
163165

166+
/**
167+
* Registers Jdk8Module for handling Optional and other JDK8 types.
168+
*
169+
* @return this builder for chaining
170+
*/
171+
public JsonMapperBuilder registerJdk8Module() {
172+
mapper.registerModule(new Jdk8Module());
173+
return this;
174+
}
175+
164176
/**
165177
* Disables serializing dates as timestamps (uses ISO format instead).
166178
*
@@ -419,4 +431,4 @@ public XmlMapperBuilder enableOutputXML11() {
419431
return this;
420432
}
421433
}
422-
}
434+
}

0 commit comments

Comments
 (0)