Skip to content

Commit

Permalink
Tests passing up to model-impl (excluding).
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Oct 22, 2016
1 parent 45d2230 commit e5f5b13
Show file tree
Hide file tree
Showing 34 changed files with 830 additions and 208 deletions.
Expand Up @@ -198,6 +198,7 @@ public boolean isAuxiliary() {
return structuralObjectClassDefinition.isAuxiliary();
}

// TODO - ok???
public Collection<RefinedAssociationDefinition> getAssociations() {
return structuralObjectClassDefinition.getAssociations();
}
Expand All @@ -206,10 +207,6 @@ public Collection<RefinedAssociationDefinition> getAssociations(ShadowKindType k
return structuralObjectClassDefinition.getAssociations(kind);
}

public Collection<RefinedAssociationDefinition> getEntitlementAssociations() {
return structuralObjectClassDefinition.getEntitlementAssociations();
}

public Collection<QName> getNamesOfAssociations() {
return structuralObjectClassDefinition.getNamesOfAssociations();
}
Expand Down Expand Up @@ -389,14 +386,26 @@ public <X> RefinedAttributeDefinition<X> findAttributeDefinition(QName elementQN
return (RefinedAttributeDefinition<X>) findItemDefinition(elementQName, RefinedAttributeDefinition.class, caseInsensitive);
}

@Override
public RefinedAssociationDefinition findAssociation(QName name) {
throw new UnsupportedOperationException("TODO implement if needed");
for (RefinedAssociationDefinition assocType: getAssociations()) {
if (QNameUtil.match(assocType.getName(), name)) {
return assocType;
}
}
return null;
}

public Collection<RefinedAssociationDefinition> getEntitlementAssociations() {
return getAssociations(ShadowKindType.ENTITLEMENT);
}

@Override
public RefinedAssociationDefinition findEntitlementAssociation(QName name) {
throw new UnsupportedOperationException("TODO implement if needed");
for (RefinedAssociationDefinition assocType: getEntitlementAssociations()) {
if (QNameUtil.match(assocType.getName(), name)) {
return assocType;
}
}
return null;
}

@Override
Expand Down
Expand Up @@ -460,4 +460,9 @@ public String getDocClassName() {
return "complex type";
}

// @Override
// public void accept(Visitor visitor) {
// super.accept(visitor);
// itemDefinitions.forEach(def -> def.accept(visitor));
// }
}
Expand Up @@ -293,4 +293,9 @@ public String debugDump(int indent) {

@Override
public abstract Definition clone();

// @Override
// public void accept(Visitor visitor) {
// visitor.visit(this);
// }
}
Expand Up @@ -186,6 +186,11 @@ public PrismContext getPrismContext() {
return null;
}
}

// Primarily for testing
public PrismContext getPrismContextLocal() {
return prismContext;
}

public void setPrismContext(PrismContext prismContext) {
this.prismContext = prismContext;
Expand Down
Expand Up @@ -109,7 +109,12 @@ public PrismContext getPrismContext() {
return null;
}

/**
// Primarily for testing
public PrismContext getPrismContextLocal() {
return prismContext;
}

/**
* Returns a set of items that the property container contains. The items may be properties or inner property containers.
* <p/>
* The set may be null. In case there are no properties an empty set is
Expand Down Expand Up @@ -251,24 +256,39 @@ public C asContainerable() {
return asContainerableInternal(resolveClass(null));
}

public C asContainerable(Class<C> defaultClass) {
// returned class must be of type 'requiredClass' (or any of its subtypes)
public C asContainerable(Class<C> requiredClass) {
if (containerable != null) {
return containerable;
}
return asContainerableInternal(resolveClass(defaultClass));
return asContainerableInternal(resolveClass(requiredClass));
}

private Class<C> resolveClass(Class<C> defaultClass) {
Class<C> clazz = defaultClass;
private Class<C> resolveClass(@Nullable Class<C> requiredClass) {
if (complexTypeDefinition != null && complexTypeDefinition.getCompileTimeClass() != null) {
clazz = (Class<C>) complexTypeDefinition.getCompileTimeClass();
Class<?> actualClass = complexTypeDefinition.getCompileTimeClass();
if (requiredClass != null && !requiredClass.isAssignableFrom(actualClass)) {
throw new IllegalStateException("asContainerable was called to produce " + requiredClass
+ ", but the actual class in PCV is " + actualClass);
} else {
return (Class<C>) actualClass;
}
} else {
PrismContainerable parent = getParent();
if (parent != null && parent.getCompileTimeClass() != null) {
clazz = parent.getCompileTimeClass(); // TODO is this ok?
if (parent != null) {
Class<?> parentClass = parent.getCompileTimeClass();
if (parentClass != null) {
if (requiredClass != null && !requiredClass.isAssignableFrom(parentClass)) {
// mismatch; but this can occur (see ShadowAttributesType vs ShadowIdentifiersType in ShadowAssociationType)
// but TODO maybe this is only a workaround and the problem is in the schema itself (?)
return requiredClass;
} else {
return (Class<C>) parentClass;
}
}
}
}
return clazz;
return requiredClass;
}

private C asContainerableInternal(Class<C> clazz) {
Expand Down
Expand Up @@ -53,7 +53,10 @@
* 4. name from item definition derived from type name
* 5. name from item definition derived from type class
*
* General post-condition: All recognizable definitions are set. This is true for items as well as item values.
* General post-conditions: (For items as well as item values; and for all parsing methods.)
* - All recognizable definitions are set.
* - Prism context is set on all items and PCVs.
* - No unresolved raw values with known types are present.
*
* @author mederly
*/
Expand Down
Expand Up @@ -117,28 +117,28 @@ public T getValue() {
if (parent != null && parent.getDefinition() != null) {
def = getParent().getDefinition();
}
if (def == null) {
// We are weak now. If there is no better definition for this we assume a default definition and process
// the attribute now. But we should rather do this: TODO:
// throw new IllegalStateException("Attempt to get value withot a type from raw value of property "+getParent());
if (parent != null && getPrismContext() != null) {
def = SchemaRegistryImpl.createDefaultItemDefinition(parent.getElementName(), getPrismContext());
} else if (PrismContextImpl.isAllowSchemalessSerialization()) {
if (rawElement instanceof PrimitiveXNode) {
try {
QName type = rawElement.getTypeQName() != null ? rawElement.getTypeQName() : DOMUtil.XSD_STRING;
value = (T) ((PrimitiveXNode) rawElement).getParsedValueWithoutRecording(type);
} catch (SchemaException ex){
throw new IllegalStateException("Cannot fetch value from raw element. " + ex.getMessage(), ex);
}
} else {
throw new IllegalStateException("No parent or prism context in property value "+this+", cannot create default definition." +
"The element is also not a DOM element but it is "+rawElement.getClass()+". Epic fail.");
}
} else {
throw new IllegalStateException("No parent or prism context in property value "+this+" (schemaless serialization is disabled)");
}
}
// if (def == null) {
// // We are weak now. If there is no better definition for this we assume a default definition and process
// // the attribute now. But we should rather do this: TODO:
// // throw new IllegalStateException("Attempt to get value withot a type from raw value of property "+getParent());
// if (parent != null && getPrismContext() != null) {
// def = SchemaRegistryImpl.createDefaultItemDefinition(parent.getElementName(), getPrismContext());
// } else if (PrismContextImpl.isAllowSchemalessSerialization()) {
// if (rawElement instanceof PrimitiveXNode) {
// try {
// QName type = rawElement.getTypeQName() != null ? rawElement.getTypeQName() : DOMUtil.XSD_STRING;
// value = (T) ((PrimitiveXNode) rawElement).getParsedValueWithoutRecording(type);
// } catch (SchemaException ex){
// throw new IllegalStateException("Cannot fetch value from raw element. " + ex.getMessage(), ex);
// }
// } else {
// throw new IllegalStateException("No parent or prism context in property value "+this+", cannot create default definition." +
// "The element is also not a DOM element but it is "+rawElement.getClass()+". Epic fail.");
// }
// } else {
// throw new IllegalStateException("No parent or prism context in property value "+this+" (schemaless serialization is disabled)");
// }
// }
if (def != null) {
try {
applyDefinition(def);
Expand Down
Expand Up @@ -34,6 +34,7 @@ public class ItemInfo<ID extends ItemDefinition> {
private QName itemName;
private ID itemDefinition;
private QName typeName;
private ComplexTypeDefinition complexTypeDefinition;

/**
* This method is to be called ONLY on the root level, i.e. when unmarshalling starts.
Expand Down Expand Up @@ -118,6 +119,21 @@ public static <ID extends ItemDefinition> ItemInfo determine(ItemDefinition item
} else {
info.typeName = typeNameExplicit;
}

// complex type definition
if (info.itemDefinition != null) {
if (info.itemDefinition instanceof PrismContainerDefinition) {
info.complexTypeDefinition = ((PrismContainerDefinition) info.itemDefinition).getComplexTypeDefinition();
} else {
info.complexTypeDefinition = null;
}
} else if (info.typeName != null) {
// TODO probably optimize (e.g. if we already know the class ... )
info.complexTypeDefinition = schemaRegistry.findComplexTypeDefinitionByType(info.typeName);
} else {
info.complexTypeDefinition = null;
}

return info;
}

Expand Down Expand Up @@ -200,6 +216,10 @@ public ID getItemDefinition() {
return itemDefinition;
}

public ComplexTypeDefinition getComplexTypeDefinition() {
return complexTypeDefinition;
}

public QName getTypeName() {
return typeName;
}
Expand Down
Expand Up @@ -650,7 +650,15 @@ private Object convertSinglePropValue(XNode xsubnode, String fieldName, Class pa
} else if (paramType.equals(XNode.class)) {
propValue = xsubnode;
} else if (storeAsRawType || paramType.equals(RawType.class)) {
propValue = new RawType(xsubnode, prismContext);
RawType raw = new RawType(xsubnode, prismContext);
// FIXME UGLY HACK: parse value if possible
if (xsubnode.getTypeQName() != null) {
PrismValue value = prismContext.parserFor(xsubnode.toRootXNode()).parseItemValue();
if (value != null && !value.isRaw()) {
raw = new RawType(value, prismContext);
}
}
propValue = raw;
} else {
// paramType is what we expect e.g. based on parent definition
// but actual type (given by xsi:type/@typeDef) may be different, e.g. more specific
Expand Down Expand Up @@ -707,14 +715,24 @@ private <T> T unmarshallPrimitive(PrimitiveXNode<?> xprim, Class<T> classType, P
}

if (PolyStringType.class.isAssignableFrom(classType)) {
String value = (String) xprim.getParsedValue(DOMUtil.XSD_STRING);
PolyString polyString = new PolyString(value);
if (value != null) {
if (prismContext != null) { // actually this should be always so [med]
// TODO should we always use default normalizer?
polyString.recompute(prismContext.getDefaultPolyStringNormalizer());
}
}
// TODO fixme this hack
Object value = xprim.getParsedValue(DOMUtil.XSD_STRING);
PolyString polyString;
if (value instanceof String) {
polyString = new PolyString((String) value);
} else if (value instanceof PolyStringType) {
polyString = ((PolyStringType) value).toPolyString();
} else if (value instanceof PolyString) {
polyString = (PolyString) value; // TODO clone?
} else if (value == null) {
polyString = null;
} else {
throw new IllegalStateException("Couldn't convert " + value + " to a PolyString; while parsing " + xprim.debugDump());
}
if (polyString != null) {
// TODO should we always use default normalizer?
polyString.recompute(prismContext.getDefaultPolyStringNormalizer());
}
return (T) new PolyStringType(polyString);
}

Expand Down

0 comments on commit e5f5b13

Please sign in to comment.