Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ByteArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.DateSchema;
import io.swagger.v3.oas.models.media.DateTimeSchema;
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.Encoding;
import io.swagger.v3.oas.models.media.MediaType;
Expand Down Expand Up @@ -56,10 +59,13 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Calendar.*;


public class OpenAPIDeserializer {
Expand Down Expand Up @@ -94,6 +100,9 @@ public class OpenAPIDeserializer {
private static final String COOKIE_PARAMETER = "cookie";
private static final String PATH_PARAMETER = "path";
private static final String HEADER_PARAMETER = "header";
private static final Pattern RFC3339_DATE_TIME_PATTERN = Pattern.compile( "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(\\.\\d+)?((Z)|([+-]\\d{2}:\\d{2}))$");
private static final Pattern RFC3339_DATE_PATTERN = Pattern.compile( "^(\\d{4})-(\\d{2})-(\\d{2})$");

private Components components;
private final Set<String> operationIDs = new HashSet<>();

Expand Down Expand Up @@ -2201,8 +2210,13 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){
for (JsonNode n : enumArray) {
if (n.isNumber()) {
schema.addEnumItemObject(n.numberValue());
}else if (n.isValueNode()) {
schema.addEnumItemObject(n.asText());
} else if (n.isValueNode()) {
try {
schema.addEnumItemObject( getDecodedObject( schema, n.asText(null)));
}
catch( ParseException e) {
result.invalidType( location, String.format( "enum=`%s`", e.getMessage()), schema.getFormat(), n);
}
} else {
result.invalidType(location, "enum", "value", n);
}
Expand Down Expand Up @@ -2291,7 +2305,12 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){
}else if(schema.getType().equals("string")) {
value = getString("default", node, false, location, result);
if (value != null) {
schema.setDefault(value);
try {
schema.setDefault( getDecodedObject( schema, value));
}
catch( ParseException e) {
result.invalidType( location, String.format( "default=`%s`", e.getMessage()), schema.getFormat(), node);
}
}
}else if(schema.getType().equals("boolean")) {
bool = getBoolean("default", node, false, location, result);
Expand Down Expand Up @@ -2375,6 +2394,121 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){
}


/**
* Decodes the given string and returns an object applicable to the given schema.
* Throws a ParseException if no applicable object can be recognized.
*/
private Object getDecodedObject( Schema schema, String objectString) throws ParseException {
Object object =
objectString == null?
null :

schema.getClass().equals( DateSchema.class)?
toDate( objectString) :

schema.getClass().equals( DateTimeSchema.class)?
toDateTime( objectString) :

schema.getClass().equals( ByteArraySchema.class)?
toBytes( objectString) :

objectString;

if( object == null && objectString != null) {
throw new ParseException( objectString, 0);
}

return object;
}


/**
* Returns the Date represented by the given RFC3339 date-time string.
* Returns null if this string can't be parsed as Date.
*/
private Date toDateTime( String dateString) {
// Note: For this conversion, regex matching is better than SimpleDateFormat, etc.
// Optional elements (e.g. milliseconds) are not directly handled by SimpleDateFormat.
// Also, SimpleDateFormat is not thread-safe.
Matcher matcher = RFC3339_DATE_TIME_PATTERN.matcher( dateString);

Date dateTime = null;
if( matcher.matches()) {
try {
String year = matcher.group(1);
String month = matcher.group(2);
String day = matcher.group(3);
String hour = matcher.group(4);
String min = matcher.group(5);
String sec = matcher.group(6);
String ms = matcher.group(7);
String zone = matcher.group(10);

Calendar calendar = Calendar.getInstance( TimeZone.getTimeZone( zone == null? "GMT" : "GMT" + zone));
calendar.set( YEAR, Integer.parseInt( year));
calendar.set( MONTH, Integer.parseInt( month) - 1);
calendar.set( DAY_OF_MONTH, Integer.parseInt( day));
calendar.set( HOUR_OF_DAY, Integer.parseInt( hour));
calendar.set( MINUTE, Integer.parseInt( min));
calendar.set( SECOND, Integer.parseInt( sec));
calendar.set( MILLISECOND, ms == null? 0 : (int) (Double.parseDouble( ms) * 1000));

dateTime = calendar.getTime();
}
catch( Exception ignore) {
}
}

return dateTime;
}


/**
* Returns the Date represented by the given RFC3339 full-date string.
* Returns null if this string can't be parsed as Date.
*/
private Date toDate( String dateString) {
Matcher matcher = RFC3339_DATE_PATTERN.matcher( dateString);

Date date = null;
if( matcher.matches()) {
String year = matcher.group(1);
String month = matcher.group(2);
String day = matcher.group(3);

try {
date=
new Calendar.Builder()
.setDate( Integer.parseInt( year), Integer.parseInt( month) - 1, Integer.parseInt( day))
.build()
.getTime();
}
catch( Exception ignore) {
}
}

return date;
}


/**
* Returns the byte array represented by the given base64-encoded string.
* Returns null if this string is not a valid base64 encoding.
*/
private byte[] toBytes( String byteString) {
byte[] bytes;

try {
bytes = Base64.getDecoder().decode( byteString);
}
catch( Exception e) {
bytes = null;
}

return bytes;
}




public Map<String, Example> getExamples(ObjectNode obj, String location, ParseResult result) {
Expand Down
Loading