
org.everit.json.schema.loader.ReferenceLookup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.search.experiences.service
Show all versions of com.liferay.search.experiences.service
Liferay Search Experiences Service
The newest version!
package org.everit.json.schema.loader;
import static java.util.Objects.requireNonNull;
import static org.everit.json.schema.loader.OrgJsonUtil.toMap;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.everit.json.schema.ReferenceSchema;
import org.everit.json.schema.Schema;
import org.everit.json.schema.SchemaLocation;
import org.everit.json.schema.loader.internal.ReferenceResolver;
import org.json.JSONObject;
class ReferenceKnot {
private Schema referredSchema;
private List refs = new ArrayList<>(1);
ReferenceSchema.Builder initReference(String refValue) {
ReferenceSchema.Builder builder = new ReferenceSchema.Builder().refValue(refValue);
if (referredSchema != null) {
builder.build().setReferredSchema(referredSchema);
}
refs.add(builder);
return builder;
}
void resolveWith(Schema referredSchema) {
refs.forEach(ref -> ref.build().setReferredSchema(referredSchema));
this.referredSchema = referredSchema;
}
}
/**
* @author erosb
*/
class ReferenceLookup {
/**
* Underscore-like extend function. Merges the properties of {@code additional} and
* {@code original}. Neither {@code additional} nor {@code original} will be modified, but the
* returned object may be referentially the same as one of the parameters (in case the other
* parameter is an empty object).
*/
@Deprecated
static JSONObject extend(JSONObject additional, JSONObject original) {
return new JSONObject(extend(toMap(additional), toMap(original)));
}
static Map extend(Map additional, Map original) {
if (additional.keySet().isEmpty()) {
return original;
}
if (original.keySet().isEmpty()) {
return additional;
}
Map rawObj = new HashMap<>();
original.forEach(rawObj::put);
additional.forEach(rawObj::put);
return rawObj;
}
private LoadingState ls;
private SchemaClient schemaClient;
public ReferenceLookup(LoadingState ls) {
this.ls = requireNonNull(ls, "ls cannot be null");
this.schemaClient = ls.config.schemaClient;
}
private Map doExtend(Map additional, Map original) {
if (ls.specVersion() == SpecificationVersion.DRAFT_4) {
return extend(additional, original);
} else {
return original;
}
}
/**
* Returns the absolute URI without its fragment part.
*
* @param fullUri
* the abslute URI
* @return the URI without the fragment part
*/
static URI withoutFragment(final String fullUri) {
int hashmarkIdx = fullUri.indexOf('#');
String rval;
if (hashmarkIdx == -1) {
rval = fullUri;
} else {
rval = fullUri.substring(0, hashmarkIdx);
}
try {
return new URI(rval);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
Map withoutRef(JsonObject original) {
Map rawObj = new HashMap<>();
original.keySet().stream()
.filter(name -> !"$ref".equals(name))
.forEach(name -> rawObj.put(name, original.get(name)));
return rawObj;
}
private JsonObject lookupObjById(JsonValue val, String idAttrVal) {
String idKeyword = val.ls.specVersion().idKeyword();
if (val instanceof JsonObject) {
JsonObject obj = (JsonObject) val;
if (obj.containsKey(idKeyword)
&& obj.require(idKeyword).typeOfValue() == String.class
&& obj.require(idKeyword).requireString().equals(idAttrVal)) {
return obj;
}
for (String key : obj.keySet()) {
JsonObject maybeFound = lookupObjById(obj.require(key), idAttrVal);
if (maybeFound != null) {
return maybeFound;
}
}
} else if (val instanceof JsonArray) {
JsonArray arr = (JsonArray) val;
for (int i = 0; i < arr.length(); ++i) {
JsonObject maybeFound = lookupObjById(arr.at(i), idAttrVal);
if (maybeFound != null) {
return maybeFound;
}
}
}
return null;
}
private Schema.Builder> performQueryEvaluation(String mapKey, JsonPointerEvaluator pointerEvaluator) {
String absolutePointer = ReferenceResolver.resolve(ls.id, mapKey).toString();
if (ls.pointerSchemas.containsKey(absolutePointer)) {
return ls.pointerSchemas.get(absolutePointer).initReference(absolutePointer);
}
JsonValue referencedRawSchema = pointerEvaluator.query().getQueryResult();
return createReferenceSchema(mapKey, absolutePointer, referencedRawSchema);
}
/**
* Returns a schema builder instance after looking up the JSON pointer.
*/
Schema.Builder> lookup(String relPointerString, JsonObject ctx) {
String absPointerString = ReferenceResolver.resolve(ls.id, relPointerString).toString();
if (ls.pointerSchemas.containsKey(absPointerString)) {
return ls.pointerSchemas.get(absPointerString).initReference(absPointerString);
}
JsonValue rawInternalReferenced = lookupObjById(ls.rootSchemaJson, absPointerString);
if (rawInternalReferenced != null) {
return createReferenceSchema(relPointerString, absPointerString, rawInternalReferenced);
}
if (isSameDocumentRef(relPointerString)) {
return performQueryEvaluation(relPointerString, JsonPointerEvaluator.forDocument(ls.rootSchemaJson(), relPointerString));
}
JsonPointerEvaluator pointer = createPointerEvaluator(absPointerString);
ReferenceKnot knot = new ReferenceKnot();
ReferenceSchema.Builder refBuilder = knot.initReference(relPointerString);
ls.pointerSchemas.put(absPointerString, knot);
JsonPointerEvaluator.QueryResult result = pointer.query();
URI resolutionScope = !isSameDocumentRef(absPointerString) ? withoutFragment(absPointerString) : ls.id;
JsonObject containingDocument = result.getContainingDocument();
SchemaLoader childLoader = ls.initNewDocumentLoader()
.pointerToCurrentObj(SchemaLocation.parseURI(absPointerString))
.resolutionScope(resolutionScope)
.schemaJson(result.getQueryResult())
.rootSchemaJson(containingDocument).build();
Schema referredSchema = childLoader.load().build();
refBuilder.schemaLocation(SchemaLocation.parseURI(absPointerString));
knot.resolveWith(referredSchema);
return refBuilder;
}
private Schema.Builder> createReferenceSchema(String relPointerString, String absPointerString, JsonValue rawReferenced) {
ReferenceKnot knot = new ReferenceKnot();
ReferenceSchema.Builder refBuilder = knot.initReference(relPointerString);
ls.pointerSchemas.put(absPointerString, knot);
Schema referredSchema = new SchemaLoader(rawReferenced.ls).load().build();
knot.resolveWith(referredSchema);
return refBuilder;
}
private JsonObject initJsonObjectById(URI id) {
JsonObject o = JsonValue.of(ls.config.schemasByURI.get(id)).requireObject();
new LoadingState(ls.config, ls.pointerSchemas, o, o, id, SchemaLocation.parseURI(id.toString()));
return o;
}
private JsonPointerEvaluator createPointerEvaluator(String absPointerString) {
if (isSameDocumentRef(absPointerString)) {
return JsonPointerEvaluator.forDocument(ls.rootSchemaJson(), absPointerString);
}
try {
Uri uri = Uri.parse(absPointerString);
if (ls.config.schemasByURI.containsKey(uri.asJavaURI())) {
JsonObject o = initJsonObjectById(uri.asJavaURI());
return JsonPointerEvaluator.forDocument(o, "#");
} else if (ls.config.schemasByURI.containsKey(uri.toBeQueried)) {
JsonObject o = initJsonObjectById(uri.toBeQueried);
return JsonPointerEvaluator.forDocument(o, uri.fragment);
}
} catch (URISyntaxException e) {
throw ls.createSchemaException(e);
}
return JsonPointerEvaluator.forURL(schemaClient, absPointerString, ls);
}
private boolean isSameDocumentRef(String ref) {
return ref.startsWith("#");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy