Skip to content

Commit

Permalink
Fixed parsing of specific subtypes that have CTD but not item definit…
Browse files Browse the repository at this point in the history
…ion (ConditionalSearchFilterType).
  • Loading branch information
mederly committed Oct 26, 2016
1 parent cbddfc4 commit 06f2851
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 12 deletions.
Expand Up @@ -63,9 +63,24 @@ public static <ID extends ItemDefinition> ItemInfo determine(ItemDefinition item
definition = augmentWithType(definition, definitionClass, schemaRegistry, typeNameExplicit);
definition = augmentWithType(definition, definitionClass, schemaRegistry, typeNameFromSource);
definition = augmentWithClass(definition, definitionClass, schemaRegistry, classExplicit);

definition = augmentWithItemName(definition, definitionClass, schemaRegistry, itemNameFromSource);

// Sanity check: if typeNameFromSource or typeNameExplicit are not compatible with the type derived from definition,
// we will NOT use the definition. For example, if client is looking for ConditionalSearchFilterType (has no ItemDefinition)
// the definition here would be very probably SearchFilterType (based e.g. on the itemNameFromSource). And it has not
// to be used, as the client explicitly requested ConditionalSearchFilterType.
//
// Exception is PrismReferenceDefinition, as there are no subtypes in that case (yet)
if (definition != null && !(definition instanceof PrismReferenceDefinition)) {
QName typeName = definition.getTypeName();
if (typeNameExplicit != null && !schemaRegistry.isAssignableFrom(typeNameExplicit, typeName)
|| typeNameFromSource != null && !schemaRegistry.isAssignableFrom(typeNameFromSource, typeName)) {
// the result would NOT match typeNameExplicit/typeNameFromSource (very probably)
// so we have to abandon this definition
definition = null;
}
}

ItemInfo<ID> info = new ItemInfo<>();
info.itemDefinition = definition;

Expand Down
Expand Up @@ -94,10 +94,17 @@ <O extends Objectable> PrismObject<O> parseObject(MapXNode map, PrismObjectDefin
ItemDefinition realDefinition;
if (itemInfo.getItemDefinition() == null && itemInfo.getComplexTypeDefinition() != null) {
// let's create container definition dynamically
PrismContainerDefinitionImpl pcd = new PrismContainerDefinitionImpl(itemInfo.getItemName(), itemInfo.getComplexTypeDefinition(),
prismContext);
pcd.setDynamic(true); // questionable
realDefinition = pcd;
QName actualTypeName = itemInfo.getComplexTypeDefinition().getTypeName();
if (getSchemaRegistry().isContainer(actualTypeName)) {
PrismContainerDefinitionImpl def = new PrismContainerDefinitionImpl(itemInfo.getItemName(),
itemInfo.getComplexTypeDefinition(), prismContext);
def.setDynamic(true);
realDefinition = def;
} else {
PrismPropertyDefinitionImpl def = new PrismPropertyDefinitionImpl(itemInfo.getItemName(), actualTypeName, prismContext);
def.setDynamic(true);
realDefinition = def;
}
} else {
realDefinition = itemInfo.getItemDefinition();
}
Expand Down
Expand Up @@ -425,7 +425,7 @@ private static <C extends Containerable> RefFilter parseRefFilter(MapXNode claus

ItemDefinition itemDefinition = null;
if (pcd != null) {
itemDefinition = pcd != null ? pcd.findItemDefinition(itemPath) : null;
itemDefinition = pcd.findItemDefinition(itemPath);
if (itemDefinition == null && !preliminaryParsingOnly) {
throw new SchemaException("No definition for item "+itemPath+" in "+pcd);
}
Expand All @@ -442,6 +442,9 @@ private static <C extends Containerable> RefFilter parseRefFilter(MapXNode claus
.definition(itemDefinition)
.context(ParsingContext.allowMissingRefTypes())
.parseItem();
if (!(item instanceof PrismReference)) {
throw new IllegalStateException("Expected PrismReference, got " + item);
}
PrismReference ref = (PrismReference)item;
if (item.getValues().size() < 1) {
throw new IllegalStateException("No values to search specified for item " + itemName);
Expand Down
Expand Up @@ -147,6 +147,8 @@ <ID extends ItemDefinition> ID selectMoreSpecific(ID def1, ID def2)
QName selectMoreSpecific(QName type1, QName type2)
throws SchemaException;

boolean isContainer(QName typeName);

enum ComparisonResult {
EQUAL, // types are equal
NO_STATIC_CLASS, // static class cannot be determined
Expand All @@ -157,8 +159,8 @@ enum ComparisonResult {
/**
* @return null means we cannot decide (types are different, and no compile time class for def1 and/or def2)
*/
<ID extends ItemDefinition> ComparisonResult compareDefinitions(ID def1, ID def2)
<ID extends ItemDefinition> ComparisonResult compareDefinitions(@NotNull ID def1, @NotNull ID def2)
throws SchemaException;

boolean isAssignableFrom(QName superType, QName subType);
boolean isAssignableFrom(@NotNull QName superType, @NotNull QName subType);
}
Expand Up @@ -1219,6 +1219,16 @@ public <T> Class<T> determineClassForType(QName type) {
}
}

@NotNull
public <T> Class<T> determineClassForTypeNotNull(QName typeName) {
Class<T> clazz = determineClassForType(typeName);
if (clazz != null) {
return clazz;
} else {
throw new IllegalStateException("No class for " + typeName);
}
}

@Override
public Class<?> determineClassForItemDefinition(ItemDefinition<?> itemDefinition) {
if (itemDefinition instanceof PrismContainerDefinition) {
Expand Down Expand Up @@ -1319,12 +1329,22 @@ public <ID extends ItemDefinition> ComparisonResult compareDefinitions(@NotNull

@Override
public boolean isAssignableFrom(@NotNull QName superType, @NotNull QName subType) {
if (QNameUtil.match(superType, subType)) {
if (QNameUtil.match(superType, subType) || QNameUtil.match(DOMUtil.XSD_ANYTYPE, superType)) {
return true;
}
Class<?> superClass = determineCompileTimeClassNotNull(superType);
Class<?> subClass = determineCompileTimeClassNotNull(subType);
if (QNameUtil.match(DOMUtil.XSD_ANYTYPE, subType)) {
return false;
}
Class<?> superClass = determineClassForTypeNotNull(superType);
Class<?> subClass = determineClassForTypeNotNull(subType);
return superClass.isAssignableFrom(subClass);
}

@Override
public boolean isContainer(QName typeName) {
Class<?> clazz = determineClassForType(typeName);
return clazz != null && Containerable.class.isAssignableFrom(clazz);
}

//endregion
}
Expand Up @@ -60,7 +60,7 @@ public void testParseFile() throws Exception {

private void processParsings(SerializingFunction<PrismPropertyValue<MappingType>> serializer, String serId) throws Exception {
PrismPropertyDefinition definition = getPrismContext().getSchemaRegistry().findPropertyDefinitionByElementName(SchemaConstantsGenerated.C_MAPPING);
processParsings(MappingType.class, MappingsType.COMPLEX_TYPE, definition, serializer, serId);
processParsings(MappingType.class, MappingType.COMPLEX_TYPE, definition, serializer, serId);
}

// a bit of hack: RawType gets parsed very soon, so we must test for it almost immediately after parsing
Expand Down

0 comments on commit 06f2851

Please sign in to comment.