Skip to content

Commit 0b5ca10

Browse files
committed
Manual merge of #1356 from 2.19 to master (merge conflicts)
1 parent b8b367e commit 0b5ca10

File tree

1 file changed

+75
-50
lines changed

1 file changed

+75
-50
lines changed

src/main/java/tools/jackson/core/JsonGenerator.java

+75-50
Original file line numberDiff line numberDiff line change
@@ -1378,63 +1378,88 @@ public JsonGenerator writeTypeId(Object id) throws JacksonException {
13781378
public WritableTypeId writeTypePrefix(WritableTypeId typeIdDef)
13791379
throws JacksonException
13801380
{
1381-
Object id = typeIdDef.id;
1382-
1383-
final JsonToken valueShape = typeIdDef.valueShape;
1384-
if (canWriteTypeId()) {
1385-
typeIdDef.wrapperWritten = false;
1386-
// just rely on native type output method (sub-classes likely to override)
1387-
writeTypeId(id);
1388-
} else {
1389-
// No native type id; write wrappers
1390-
// Normally we only support String type ids (non-String reserved for native type ids)
1391-
String idStr = (id instanceof String) ? (String) id : String.valueOf(id);
1392-
typeIdDef.wrapperWritten = true;
1393-
1394-
Inclusion incl = typeIdDef.include;
1395-
// first: can not output "as property" if value not Object; if so, must do "as array"
1396-
if ((valueShape != JsonToken.START_OBJECT)
1397-
&& incl.requiresObjectContext()) {
1398-
typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY;
1381+
final boolean wasStartObjectWritten = canWriteTypeId()
1382+
? _writeTypePrefixUsingNative(typeIdDef)
1383+
: _writeTypePrefixUsingWrapper(typeIdDef);
1384+
1385+
// And then possible start marker for value itself:
1386+
switch (typeIdDef.valueShape) {
1387+
case START_OBJECT:
1388+
if (!wasStartObjectWritten) {
1389+
writeStartObject(typeIdDef.forValue);
13991390
}
1391+
break;
1392+
case START_ARRAY:
1393+
writeStartArray(typeIdDef.forValue);
1394+
break;
1395+
default: // otherwise: no start marker
1396+
}
14001397

1401-
switch (incl) {
1402-
case PARENT_PROPERTY:
1403-
// nothing to do here, as it has to be written in suffix...
1404-
break;
1405-
case PAYLOAD_PROPERTY:
1406-
// only output as native type id; otherwise caller must handle using some
1407-
// other mechanism, so...
1408-
break;
1409-
case METADATA_PROPERTY:
1410-
// must have Object context by now, so simply write as property name
1411-
// Note, too, that it's bit tricky, since we must print START_OBJECT that is part
1412-
// of value first -- and then NOT output it later on: hence return "early"
1413-
writeStartObject(typeIdDef.forValue);
1414-
writeStringProperty(typeIdDef.asProperty, idStr);
1415-
return typeIdDef;
1398+
return typeIdDef;
1399+
}
14161400

1417-
case WRAPPER_OBJECT:
1418-
// NOTE: this is wrapper, not directly related to value to output, so don't pass
1419-
writeStartObject();
1420-
writeName(idStr);
1421-
break;
1422-
case WRAPPER_ARRAY:
1423-
default: // should never occur but translate as "as-array"
1424-
writeStartArray(); // wrapper, not actual array object to write
1425-
writeString(idStr);
1426-
}
1401+
/**
1402+
* Writes a native type id (when supported by format).
1403+
*
1404+
* @return True if start of an object has been written, False otherwise.
1405+
*/
1406+
protected boolean _writeTypePrefixUsingNative(WritableTypeId typeIdDef) throws JacksonException {
1407+
typeIdDef.wrapperWritten = false;
1408+
writeTypeId(typeIdDef.id);
1409+
return false;
1410+
}
1411+
1412+
/**
1413+
* Writes a wrapper for the type id if necessary.
1414+
*
1415+
* @return True if start of an object has been written, false otherwise.
1416+
*/
1417+
protected boolean _writeTypePrefixUsingWrapper(WritableTypeId typeIdDef) throws JacksonException {
1418+
// Normally we only support String type ids (non-String reserved for native type ids)
1419+
final String id = Objects.toString(typeIdDef.id, null);
1420+
1421+
// If we don't have Type ID we don't write a wrapper.
1422+
if (id == null) {
1423+
return false;
14271424
}
1428-
// and finally possible start marker for value itself:
1429-
if (valueShape == JsonToken.START_OBJECT) {
1425+
Inclusion incl = typeIdDef.include;
1426+
1427+
// first: can not output "as property" if value not Object; if so, must do "as array"
1428+
if ((typeIdDef.valueShape != JsonToken.START_OBJECT) && incl.requiresObjectContext()) {
1429+
typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY;
1430+
}
1431+
1432+
typeIdDef.wrapperWritten = true;
1433+
switch (incl) {
1434+
case PARENT_PROPERTY:
1435+
// nothing to do here, as it has to be written in suffix...
1436+
break;
1437+
case PAYLOAD_PROPERTY:
1438+
// only output as native type id; otherwise caller must handle using some
1439+
// other mechanism, so...
1440+
break;
1441+
case METADATA_PROPERTY:
1442+
// must have Object context by now, so simply write as field name
1443+
// Note, too, that it's bit tricky, since we must print START_OBJECT that is part
1444+
// of value first -- and then NOT output it later on: hence return "early"
14301445
writeStartObject(typeIdDef.forValue);
1431-
} else if (valueShape == JsonToken.START_ARRAY) {
1432-
// should we now set the current object?
1433-
writeStartArray();
1446+
writeStringProperty(typeIdDef.asProperty, id);
1447+
return true;
1448+
1449+
case WRAPPER_OBJECT:
1450+
// NOTE: this is wrapper, not directly related to value to output, so
1451+
// do NOT pass "typeIdDef.forValue"
1452+
writeStartObject();
1453+
writeName(id);
1454+
break;
1455+
case WRAPPER_ARRAY:
1456+
default: // should never occur but translate as "as-array"
1457+
writeStartArray(); // wrapper, not actual array object to write
1458+
writeString(id);
14341459
}
1435-
return typeIdDef;
1460+
return false;
14361461
}
1437-
1462+
14381463
public WritableTypeId writeTypeSuffix(WritableTypeId typeIdDef) throws JacksonException
14391464
{
14401465
final JsonToken valueShape = typeIdDef.valueShape;

0 commit comments

Comments
 (0)