GP-661: Fixing schema issues. Fixing dbgeng/model schemas.

This commit is contained in:
Dan 2021-02-04 14:55:57 -05:00
parent 5387946fab
commit 7d5c35138a
9 changed files with 31 additions and 33 deletions

View file

@ -73,9 +73,6 @@ public abstract class AbstractTargetObject<P extends TargetObject>
this.typeHint = typeHint;
this.schema = schema;
if (schema != null) {
schema.validateTypeAndInterfaces(getProxy(), null, enforcesStrictSchema());
}
}
/**

View file

@ -239,7 +239,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateElementDelta(getProxy(), delta, enforcesStrictSchema());
schemax.validateElementDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateElements(delta.removed.values(), reason);
if (!delta.isEmpty()) {
@ -284,7 +284,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateElementDelta(getProxy(), delta, enforcesStrictSchema());
schemax.validateElementDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateElements(delta.removed.values(), reason);
if (!delta.isEmpty()) {
@ -403,7 +403,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateAttributeDelta(getProxy(), delta, enforcesStrictSchema());
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateAttributes(delta.removed, reason);
if (!delta.isEmpty()) {
@ -448,7 +448,7 @@ public class DefaultTargetObject<E extends TargetObject, P extends TargetObject>
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateAttributeDelta(getProxy(), delta, enforcesStrictSchema());
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateAttributes(delta.removed, reason);
if (!delta.isEmpty()) {

View file

@ -131,7 +131,7 @@ public interface TargetLauncher<T extends TargetLauncher<T>> extends TypedTarget
}
}
@TargetAttributeType(name = TargetMethod.PARAMETERS_ATTRIBUTE_NAME, required = true, fixed = true, hidden = true)
@TargetAttributeType(name = TargetMethod.PARAMETERS_ATTRIBUTE_NAME, required = true, hidden = true)
default public TargetParameterMap getParameters() {
return TargetMethod.getParameters(this);
}

View file

@ -19,7 +19,6 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import ghidra.dbg.DebugModelConventions;
import ghidra.dbg.agent.DefaultTargetObject;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.DefaultTargetObjectSchema.DefaultAttributeSchema;
@ -427,13 +426,16 @@ public interface TargetObjectSchema {
*
* @param value the value
*/
default void validateTypeAndInterfaces(Object value, String key, boolean strict) {
default void validateTypeAndInterfaces(Object value, List<String> parentPath, String key,
boolean strict) {
Class<?> cls = value.getClass();
if (!getType().isAssignableFrom(cls)) {
String msg = key == null
String path =
key == null ? null : PathUtils.toString(PathUtils.extend(parentPath, key));
String msg = path == null
? "Value " + value + " does not conform to required type " +
getType() + " of schema " + this
: "Value " + value + " for " + key + " does not conform to required type " +
: "Value " + value + " for " + path + " does not conform to required type " +
getType() + " of schema " + this;
if (strict) {
throw new AssertionError(msg);
@ -495,21 +497,18 @@ public interface TargetObjectSchema {
*
* @param delta the delta, before or after the fact
*/
default void validateAttributeDelta(TargetObject object, Delta<?, ?> delta, boolean strict) {
default void validateAttributeDelta(List<String> parentPath, Delta<?, ?> delta,
boolean strict) {
for (Map.Entry<String, ?> ent : delta.added.entrySet()) {
String key = ent.getKey();
Object value = ent.getValue();
AttributeSchema as = getAttributeSchema(key);
TargetObjectSchema schema = getContext().getSchema(as.getSchema());
/**
* TODO: There's some duplication of effort here, since canonical attributes will
* already have been checked at construction.
*/
schema.validateTypeAndInterfaces(value, key, strict);
schema.validateTypeAndInterfaces(value, parentPath, key, strict);
if (value instanceof TargetObject) {
TargetObject ov = (TargetObject) value;
if (!PathUtils.isLink(object.getPath(), ent.getKey(), ov.getPath())) {
if (!PathUtils.isLink(parentPath, ent.getKey(), ov.getPath())) {
schema.validateRequiredAttributes(ov, strict);
}
}
@ -524,7 +523,7 @@ public interface TargetObjectSchema {
.filter(delta.getKeysRemoved()::contains)
.collect(Collectors.toSet());
if (!violatesRequired.isEmpty()) {
String msg = "Object " + object + " removed required attributes " +
String msg = "Object " + parentPath + " removed required attributes " +
violatesRequired + " of schema " + this;
if (strict) {
throw new AssertionError(msg);
@ -542,10 +541,7 @@ public interface TargetObjectSchema {
.filter(delta.removed::containsKey)
.collect(Collectors.toSet());
if (!violatesFixed.isEmpty()) {
if (strict) {
}
String msg = "Object " + object + " modified or removed fixed attributes " +
String msg = "Object " + parentPath + " modified or removed fixed attributes " +
violatesFixed + " of schema " + this;
if (strict) {
throw new AssertionError(msg);
@ -563,11 +559,14 @@ public interface TargetObjectSchema {
*
* @param delta the delta, before or after the fact
*/
default void validateElementDelta(TargetObject object, Delta<?, ? extends TargetObject> delta,
default void validateElementDelta(List<String> parentPath,
Delta<?, ? extends TargetObject> delta,
boolean strict) {
for (Map.Entry<String, ? extends TargetObject> ent : delta.added.entrySet()) {
TargetObject element = ent.getValue();
TargetObjectSchema schema = getContext().getSchema(getElementSchema(ent.getKey()));
schema.validateRequiredAttributes(ent.getValue(), strict);
schema.validateTypeAndInterfaces(element, parentPath, ent.getKey(), strict);
schema.validateRequiredAttributes(element, strict);
}
}
}

View file

@ -133,7 +133,8 @@ public class TargetObjectSchemaValidationTest {
.addInterface(TargetAggregate.class)
.buildAndAdd();
new ValidatedModelRoot(model, "Root", schemaRoot);
schemaRoot.validateTypeAndInterfaces(new ValidatedModelRoot(model, "Root", schemaRoot),
List.of(), null, true);
// pass
}
@ -143,7 +144,8 @@ public class TargetObjectSchemaValidationTest {
.addInterface(TargetProcess.class)
.buildAndAdd();
new ValidatedModelRoot(model, "Root", schemaRoot);
schemaRoot.validateTypeAndInterfaces(new ValidatedModelRoot(model, "Root", schemaRoot),
List.of(), null, true);
}
protected ValidatedModelRoot createRootAttrWReq() {