diff --git a/core/src/main/java/org/everit/json/schema/StringToValueConverter.java b/core/src/main/java/org/everit/json/schema/StringToValueConverter.java index eede2d5c..6bf41ff4 100644 --- a/core/src/main/java/org/everit/json/schema/StringToValueConverter.java +++ b/core/src/main/java/org/everit/json/schema/StringToValueConverter.java @@ -86,11 +86,21 @@ static Object stringToValue(String string) { } private static boolean isDecimalNotation(final String val) { - return val.indexOf('.') > -1 || val.indexOf('e') > -1 - || val.indexOf('E') > -1 || "-0".equals(val); + + //Applied the REFACTORING method: "Introduce explaining variable" + /*creating a new variable to hold the result of a complex expression or calculation*/ + + boolean containsDecimalPoint = val.indexOf('.') > -1; + boolean containsExponent = val.indexOf('e') > -1 || val.indexOf('E') > -1; + boolean isNegativeZero = "-0".equals(val); + + return containsDecimalPoint || containsExponent || isNegativeZero; + + // return val.indexOf('.') > -1 || val.indexOf('e') > -1 + // || val.indexOf('E') > -1 || "-0".equals(val); } - private static Number stringToNumber(final String val) throws NumberFormatException { + /*private static Number stringToNumber(final String val) throws NumberFormatException { char initial = val.charAt(0); if ((initial >= '0' && initial <= '9') || initial == '-') { // decimal representation @@ -148,5 +158,77 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept return bi; } throw new NumberFormatException("val ["+val+"] is not a valid number."); + }*/ + + private static Number stringToNumber(final String val) throws NumberFormatException { + //Applied the REFACTORING method: "Decompose conditional:" + /*breaking down a long, complex conditional statement into smaller, more manageable pieces.*/ + char initial = val.charAt(0); + if (isValidInitialChar(initial)) { + if (isDecimalNotation(val)) { + return parseDecimal(val, initial); + } + if (isInvalidOctalNumber(val)) { + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + return parseInteger(val); + } + throw new NumberFormatException("val ["+val+"] is not a valid number."); + } + + private static boolean isValidInitialChar(char initial) { + return (initial >= '0' && initial <= '9') || initial == '-'; } + + + private static Number parseDecimal(String val, char initial) { + // Use a BigDecimal all the time so we keep the original + // representation. BigDecimal doesn't support -0.0, ensure we + // keep that by forcing a decimal. + try { + BigDecimal bd = new BigDecimal(val); + if (initial == '-' && BigDecimal.ZERO.compareTo(bd) == 0) { + return Double.valueOf(-0.0); + } + return bd; + } catch (NumberFormatException retryAsDouble) { + // this is to support "Hex Floats" like this: 0x1.0P-1074 + try { + Double d = Double.valueOf(val); + if (d.isNaN() || d.isInfinite()) { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + return d; + } catch (NumberFormatException ignore) { + throw new NumberFormatException("val [" + val + "] is not a valid number."); + } + } + } + + private static boolean isInvalidOctalNumber(String val) { + if (val.length() > 1 && val.charAt(0) == '0') { + char at1 = val.charAt(1); + if (at1 >= '0' && at1 <= '9') { + return true; + } + } else if (val.length() > 2 && val.charAt(0) == '-' && val.charAt(1) == '0') { + char at2 = val.charAt(2); + if (at2 >= '0' && at2 <= '9') { + return true; + } + } + return false; + } + + private static Number parseInteger(String val) { + BigInteger bi = new BigInteger(val); + if (bi.bitLength() <= 31) { + return Integer.valueOf(bi.intValue()); + } + if (bi.bitLength() <= 63) { + return Long.valueOf(bi.longValue()); + } + return bi; + } + } diff --git a/core/src/main/java/org/everit/json/schema/loader/JsonPointerEvaluator.java b/core/src/main/java/org/everit/json/schema/loader/JsonPointerEvaluator.java index 0d3a8d3d..1431a487 100644 --- a/core/src/main/java/org/everit/json/schema/loader/JsonPointerEvaluator.java +++ b/core/src/main/java/org/everit/json/schema/loader/JsonPointerEvaluator.java @@ -73,20 +73,26 @@ public JsonValue getQueryResult() { } private static JsonObject executeWith(final SchemaClient client, final String url) { - String resp = null; + //String resp = null; + //Applied the REFACTORING method: "Rename variable" to variables resp & reader + /*rename variable to a more meaning full name */ + String response = null; + BufferedReader buffReader = null; - InputStreamReader reader = null; + + //InputStreamReader reader = null; + InputStreamReader inputReader = null; try { InputStream responseStream = client.get(url); - reader = new InputStreamReader(responseStream, Charset.defaultCharset()); - buffReader = new BufferedReader(reader); + inputReader = new InputStreamReader(responseStream, Charset.defaultCharset()); + buffReader = new BufferedReader(inputReader); String line; StringBuilder strBuilder = new StringBuilder(); while ((line = buffReader.readLine()) != null) { strBuilder.append(line); } - resp = strBuilder.toString(); - return new JsonObject(toMap(new JSONObject(new JSONTokener(resp)))); + response = strBuilder.toString(); + return new JsonObject(toMap(new JSONObject(new JSONTokener(response)))); } catch (IOException e) { throw new UncheckedIOException(e); } catch (JSONException e) { @@ -96,8 +102,8 @@ private static JsonObject executeWith(final SchemaClient client, final String ur if (buffReader != null) { buffReader.close(); } - if (reader != null) { - reader.close(); + if (inputReader != null) { + inputReader.close(); } } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/core/src/main/java/org/everit/json/schema/loader/SchemaExtractor.java b/core/src/main/java/org/everit/json/schema/loader/SchemaExtractor.java index f721c7df..1e6f4e4c 100644 --- a/core/src/main/java/org/everit/json/schema/loader/SchemaExtractor.java +++ b/core/src/main/java/org/everit/json/schema/loader/SchemaExtractor.java @@ -100,14 +100,14 @@ abstract class AbstractSchemaExtractor implements SchemaExtractor { final SchemaLoader defaultLoader; - private ExclusiveLimitHandler exclusiveLimitHandler; + ExclusiveLimitHandler exclusiveLimitHandler; AbstractSchemaExtractor(SchemaLoader defaultLoader) { this.defaultLoader = requireNonNull(defaultLoader, "defaultLoader cannot be null"); } @Override - public final ExtractionResult extract(JsonObject schemaJson) { + public ExtractionResult extract(JsonObject schemaJson) { this.schemaJson = requireNonNull(schemaJson, "schemaJson cannot be null"); this.exclusiveLimitHandler = ExclusiveLimitHandler.ofSpecVersion(config().specVersion); consumedKeys = new KeyConsumer(schemaJson); @@ -167,6 +167,39 @@ StringSchema.Builder buildStringSchema() { abstract List> extract(); } +class NumberSchemaExtractor extends AbstractSchemaExtractor { + + private JsonObject schemaJson = null; + private final ExclusiveLimitHandler exclusiveLimitHandler; + NumberSchemaExtractor(SchemaLoader defaultLoader) { + super(defaultLoader); + this.schemaJson = schemaJson; + this.exclusiveLimitHandler = ExclusiveLimitHandler.ofSpecVersion(config().specVersion); + + } + + public ExtractionResult extract(JsonObject schemaJson) { + KeyConsumer consumedKeys = null; + PropertySnifferSchemaExtractor.NUMBER_SCHEMA_PROPS.forEach(consumedKeys::keyConsumed); + NumberSchema.Builder builder = NumberSchema.builder(); + maybe("minimum").map(JsonValue::requireNumber).ifPresent(builder::minimum); + maybe("maximum").map(JsonValue::requireNumber).ifPresent(builder::maximum); + maybe("multipleOf").map(JsonValue::requireNumber).ifPresent(multipleOf -> { + if (BigDecimal.ZERO.compareTo(BigDecimal.valueOf(multipleOf.doubleValue())) == 0) { + throw new SchemaException(schemaJson.ls.locationOfCurrentObj(), "multipleOf should not be 0"); + } + builder.multipleOf(multipleOf); + }); + maybe("exclusiveMinimum").ifPresent(exclMin -> exclusiveLimitHandler.handleExclusiveMinimum(exclMin, builder)); + maybe("exclusiveMaximum").ifPresent(exclMax -> exclusiveLimitHandler.handleExclusiveMaximum(exclMax, builder)); + return new ExtractionResult(consumedKeys.collect(), singletonList(builder)); + } + + @Override + List> extract() { + return null; + } +} class EnumSchemaExtractor extends AbstractSchemaExtractor {