Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into gui-devel
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Jul 14, 2014
2 parents 9b55d90 + 80f22d1 commit b9b6b4a
Show file tree
Hide file tree
Showing 37 changed files with 520 additions and 107 deletions.
Expand Up @@ -352,7 +352,9 @@ private InputPanel createTypedInputComponent(String id) {

InputPanel panel;
if (ActivationType.F_ADMINISTRATIVE_STATUS.equals(definition.getName())) {
return WebMiscUtil.createActivationStatusPanel(id, new PropertyModel(model, baseExpression), this);
return WebMiscUtil.createActivationStatusPanel(id, new PropertyModel<ActivationStatusType>(model, baseExpression), this);
} else if(ActivationType.F_LOCKOUT_STATUS.equals(definition.getName())){
return WebMiscUtil.createLockoutStatsPanel(id, new PropertyModel<LockoutStatusType>(model, baseExpression), this);
}

if (DOMUtil.XSD_DATETIME.equals(valueType)) {
Expand Down
Expand Up @@ -69,3 +69,6 @@ pageUser.message.noEnabledPropertyFound=No enabled property found for account '{
pageUser.message.illegalAccountState=Illegal account state '{0}'.
pageUser.message.illegalAssignmentState=Illegal assignment state '{0}'.
pageUser.message.unsupportedState=Unsupported user form state '{0}'.

LockoutStatusType.NORMAL=Normal
LockoutStatusType.LOCKED=Locked
Expand Up @@ -164,7 +164,24 @@ public String getIdValue(ActivationStatusType object, int index) {
return Integer.toString(index);
}
}, true);
}

public static DropDownChoicePanel createLockoutStatsPanel(String id, final IModel<LockoutStatusType> model,
final Component component){
return new DropDownChoicePanel(id, model,
WebMiscUtil.createReadonlyModelFromEnum(LockoutStatusType.class),
new IChoiceRenderer<LockoutStatusType>() {

@Override
public Object getDisplayValue(LockoutStatusType object) {
return WebMiscUtil.createLocalizedModelForEnum(object, component).getObject();
}

@Override
public String getIdValue(LockoutStatusType object, int index) {
return Integer.toString(index);
}
}, true);
}

public static String getName(ObjectType object) {
Expand Down
Expand Up @@ -257,7 +257,13 @@ public <T> T unmarshall(MapXNode xnode, Class<T> beanClass) throws SchemaExcepti
// This is the case of Collection<JAXBElement<?>>
// we need to exctract the specific type from the factory method
if (elementMethod == null){
throw new IllegalArgumentException("Wildcard type in JAXBElement field specification and no factory method found for field "+fieldName+" in "+beanClass+", cannot determine collection type (inner type argument)");
// TODO: TEMPORARY CODE!!!!!!!!!! fix in 3.1 [med]
Class objectFactoryClass = inspector.getObjectFactoryClass(beanClass.getPackage());
objectFactory = instantiateObjectFactory(objectFactoryClass);
elementMethod = inspector.findElementMethodInObjectFactory(objectFactoryClass, propName);
if (elementMethod == null) {
throw new IllegalArgumentException("Wildcard type in JAXBElement field specification and no factory method found for field "+fieldName+" in "+beanClass+", cannot determine collection type (inner type argument)");
}
}
Type factoryMethodGenericReturnType = elementMethod.getGenericReturnType();
Type factoryMethodTypeArgument = getTypeArgument(factoryMethodGenericReturnType, "in factory method "+elementMethod+" return type for field "+fieldName+" in "+beanClass+", cannot determine collection type");
Expand Down Expand Up @@ -715,7 +721,21 @@ public <T> XNode marshall(T bean) throws SchemaException {
elementToMarshall = ((JAXBElement) element).getValue();
}
XNode marshalled = marshallValue(elementToMarshall, fieldTypeName, isAttribute);
setExplicitTypeDeclarationIfNeeded(getter, getterResultValue, marshalled, fieldTypeName);

// Brutal hack - made here just to make scripts (bulk actions) functional while not breaking anything else
// Fix it in 3.1. [med]
if (fieldTypeName == null && element instanceof JAXBElement && marshalled != null) {
QName typeName = inspector.determineTypeForClass(elementToMarshall.getClass());
if (typeName != null) {
marshalled.setExplicitTypeDeclaration(true);
marshalled.setTypeQName(typeName);
}
}
else {
// end of hack

setExplicitTypeDeclarationIfNeeded(getter, getterResultValue, marshalled, fieldTypeName);
}
xlist.add(marshalled);
}
xmap.put(elementName, xlist);
Expand Down Expand Up @@ -847,12 +867,12 @@ private void setExplicitTypeDeclarationIfNeeded(Method getter, Object getterResu
Type genericReturnType = getter.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType){
Type actualType = getTypeArgument(genericReturnType, "explicit type declaration");

if (actualType instanceof Class){
getterType = (Class) actualType;
}
}
}
}
if (getterType == null){
getterType = getterReturnType;
}
Expand Down
Expand Up @@ -119,6 +119,17 @@ public String get(Class<? extends Object> paramType) {
});
}

private Map<Class<? extends Object>, QName> _determineTypeForClass = new HashMap<>();

QName determineTypeForClass(Class<? extends Object> paramType) {
return find1(_determineTypeForClass, paramType, new Getter1<QName,Class<? extends Object>>() {
@Override
public QName get(Class<? extends Object> paramType) {
return determineTypeForClassUncached(paramType);
}
});
}

private Map<Field,Map<Method,Boolean>> _isAttribute = new HashMap<>();

boolean isAttribute(Field field, Method getter) {
Expand Down Expand Up @@ -341,6 +352,24 @@ private String determineNamespaceUncached(Class<? extends Object> beanClass) {
return namespace;
}

private QName determineTypeForClassUncached(Class<? extends Object> beanClass) {
XmlType xmlType = beanClass.getAnnotation(XmlType.class);
if (xmlType == null) {
return null;
}

String namespace = xmlType.namespace();
if (namespace == null || PrismBeanConverter.DEFAULT_PLACEHOLDER.equals(namespace)) {
XmlSchema xmlSchema = beanClass.getPackage().getAnnotation(XmlSchema.class);
namespace = xmlSchema.namespace();
}
if (StringUtils.isBlank(namespace) || PrismBeanConverter.DEFAULT_PLACEHOLDER.equals(namespace)) {
return null;
}

return new QName(namespace, xmlType.name());
}

private <T> Method findSetterUncached(Class<T> classType, String fieldName) {
String setterName = getSetterName(fieldName);
for(Method method: classType.getMethods()) {
Expand Down
Expand Up @@ -334,8 +334,14 @@ public static void assertPropertyReplace(ObjectDelta<?> objectDelta, QName prope
assertNotNull("Property delta for "+propertyName+" not found",propertyDelta);
assertReplace(propertyDelta, expectedValues);
}

public static <T> void assertReplace(PropertyDelta<T> propertyDelta, T... expectedValues) {

public static void assertPropertyReplaceSimple(ObjectDelta<?> objectDelta, QName propertyName) {
PropertyDelta<Object> propertyDelta = objectDelta.findPropertyDelta(propertyName);
assertNotNull("Property delta for "+propertyName+" not found",propertyDelta);
assertTrue("No values to replace", propertyDelta.getValuesToReplace() != null && !propertyDelta.getValuesToReplace().isEmpty());
}

public static <T> void assertReplace(PropertyDelta<T> propertyDelta, T... expectedValues) {
assertSet("delta "+propertyDelta+" for "+propertyDelta.getElementName(), "replace", propertyDelta.getValuesToReplace(), expectedValues);
}

Expand Down Expand Up @@ -851,8 +857,12 @@ public static void assertRefFilter(ObjectFilter objectFilter, QName expectedFilt
static void assertNotNull(String string, Object object) {
assert object != null : string;
}

public static void assertEquals(String message, Object expected, Object actual) {

private static void assertTrue(String message, boolean test) {
assert test : message;
}

public static void assertEquals(String message, Object expected, Object actual) {
assert MiscUtil.equals(expected, actual) : message
+ ": expected " + MiscUtil.getValueWithClass(expected)
+ ", was " + MiscUtil.getValueWithClass(actual);
Expand Down
Expand Up @@ -270,7 +270,7 @@ public boolean equals(Object o) {
return false;
}
MapXNode other = (MapXNode) o;
return MiscUtil.unorderedCollectionEquals(this.values(), other.values());
return MiscUtil.unorderedCollectionEquals(this.entrySet(), other.entrySet());
}

public int hashCode() {
Expand Down Expand Up @@ -379,7 +379,39 @@ public XNode setValue(XNode value) {
public String toString() {
return "E(" + key + ": " + value + ")";
}

}

/**
* Compares two entries of the MapXNode.
*
* It is questionable whether to compare QNames exactly or approximately (using QNameUtil.match) here.
* For the time being, exact comparison was chosen. The immediate reason is to enable correct
* processing of diff on RawTypes (e.g. to make "debug edit" to be able to change from xyz to c:xyz
* in element names, see MID-1969).
*
* TODO: In the long run, we have to think out where exactly we want to use approximate matching of QNames.
* E.g. it is reasonable to use it only where "deployer input" is expected (e.g. import of data objects),
* not in the internals of midPoint.
*/

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Entry entry = (Entry) o;

if (key != null ? !key.equals(entry.key) : entry.key != null) return false;
if (value != null ? !value.equals(entry.value) : entry.value != null) return false;

return true;
}

@Override
public int hashCode() {
int result = key != null ? key.hashCode() : 0;
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
}
}

}
Expand Up @@ -74,7 +74,9 @@

@XmlAccessorType(XmlAccessType.NONE) // we select getters/fields to expose via JAXB individually
@XmlType(name = "SearchFilterType", propOrder = { // no prop order, because we serialize this class manually
// BTW, the order is the following: description, filterClause
})

public class SearchFilterType implements Serializable, Cloneable, Equals, HashCode, DebugDumpable, Revivable
{
private final static long serialVersionUID = 201303040000L;
Expand Down Expand Up @@ -235,12 +237,14 @@ public MapXNode serializeToXNode(PrismContext prismContext) throws SchemaExcepti
if (description == null) {
return xmap;
} else {
if (xmap == null) {
xmap = new MapXNode();
}
xmap.put(SearchFilterType.F_DESCRIPTION, new PrimitiveXNode<>(description));
// we have to serialize the map in correct order (see MID-1847): description first, filter clause next
MapXNode newXMap = new MapXNode();
newXMap.put(SearchFilterType.F_DESCRIPTION, new PrimitiveXNode<>(description));
if (xmap != null && !xmap.isEmpty()) {
newXMap.put(xmap.getSingleSubEntry("search filter"));
}
return newXMap;
}
return xmap;
}

@Override
Expand Down
Expand Up @@ -3407,9 +3407,9 @@
<xsd:element name="order" type="xsd:int" minOccurs="0" default="0">
<xsd:annotation>
<xsd:documentation>
Specifies the order in which the dependency is applied. Lower-order dependecies
Specifies the order in which the dependency is applied. Lower-order dependencies
are applied before higher-order dependencies. Dependencies with the same order
are applied at the same time. There must be no circular dependency fromed from
are applied at the same time. There must be no circular dependency formed from
dependencies of the same order.
</xsd:documentation>
</xsd:annotation>
Expand All @@ -3433,9 +3433,9 @@
<xsd:annotation>
<xsd:documentation>
If the object that we depend on is not provisioned then the dependent object will
not be provisioned either. Attempt to provision it will end up with and error.
not be provisioned either. Attempt to provision it will end up with an error.
If the object that we depend on is being provisioned in the same operation (context) as
the dependent object then they will be provisioned in order: independed first, dependent second.
the dependent object then they will be provisioned in order: independent first, dependent second.
Proper inbound-template-outbound sequence of mapping will be executed between the provisionings.
</xsd:documentation>
<xsd:appinfo>
Expand All @@ -3447,13 +3447,13 @@
<xsd:annotation>
<xsd:documentation>
If the object that we depend on is being provisioned in the same operation (context) as
the dependent object then they will be provisioned in order: independed first, dependent second.
the dependent object then they will be provisioned in order: independent first, dependent second.
Proper inbound-template-outbound sequence of mapping will be executed between the provisionings.
But no error is thrown if the dependent object is provisioned without the other object.
If both objects are being provisioned in the same operation (context) and provisioning of the
object that we depend on fails the provisioning of the dependent object will be skipped.
The relaxed strictness guarantees ordering in case that both objects are being provisioned
in the same operation (context) and delaying of the operation on dependend resource in case
in the same operation (context) and delaying of the operation on dependent resource in case
the operation on independent resource fails.
</xsd:documentation>
<xsd:appinfo>
Expand All @@ -3465,12 +3465,12 @@
<xsd:annotation>
<xsd:documentation>
If the object that we depend on is being provisioned in the same operation (context) as
the dependent object then they will be provisioned in order: independed first, dependent second.
the dependent object then they will be provisioned in order: independent first, dependent second.
Proper inbound-template-outbound sequence of mapping will be executed between the provisionings.
But NO ERROR is thrown if the dependent object is provisioned without the other object. Not even if
they are provisioned in the same operation (context) an the independend object fails.
they are provisioned in the same operation (context) an the independent object fails.
The lax strictness only guarantees ordering in case that both objects are being (successfully) provisioned.
It does not guaratee anything else.
It does not guarantee anything else.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="LAX"/>
Expand Down
Expand Up @@ -85,7 +85,7 @@
<!--</xsd:complexType>-->
<!--<xsd:element name="scriptingExpression" type="tns:ScriptingExpressionType" />-->

<xsd:element name="expression" type="xsd:anyType" abstract="true" /> <!-- because constant is anyType -->
<xsd:element name="expression" type="tns:ExpressionType" /> <!-- constants have to be treated separately -->

<xsd:complexType name="ExpressionType">
<xsd:annotation>
Expand Down Expand Up @@ -300,25 +300,30 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element ref="tns:expression" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Parameter (argument) value.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:choice>
<xsd:element ref="c:value" minOccurs="0"></xsd:element>
<xsd:element ref="tns:expression" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Parameter (argument) value.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<!--
<xsd:element name="constant" type="xsd:anyType" substitutionGroup="tns:expression" nillable="true">
<xsd:annotation>
<xsd:appinfo>
<a:rawType/>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
-->

<xsd:complexType name="ExecuteScriptType">
<xsd:sequence>
Expand Down
Expand Up @@ -137,9 +137,7 @@ public void testContextlessEquals2() throws Exception {

// (2) user with prismContext

UserType userWithContext = new UserType();
PrismContext prismContext = PrismTestUtil.getPrismContext();
prismContext.adopt(userWithContext);
UserType userWithContext = new UserType(PrismTestUtil.getPrismContext());

AssignmentType b1 = new AssignmentType(); // no prismContext here
b1.setDescription("descr1");
Expand Down
Expand Up @@ -427,13 +427,14 @@ public void testResource() throws SchemaException, SAXException, IOException, JA
assertEquals("Wrong delta OID", "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff", resourceDelta.getOid());
assertEquals("Wrong change type", ChangeType.MODIFY, resourceDelta.getChangeType());
Collection<? extends ItemDelta> modifications = resourceDelta.getModifications();
assertEquals("Unexpected number of modifications", 6, modifications.size());
assertEquals("Unexpected number of modifications", 7, modifications.size());
PrismAsserts.assertContainerDelete(resourceDelta, ResourceType.F_SCHEMA);
PrismAsserts.assertPropertyReplace(resourceDelta, pathTimeouts("update"), 3);
PrismAsserts.assertPropertyReplace(resourceDelta, pathTimeouts("scriptOnResource"), 4);
PrismAsserts.assertPropertyDelete(resourceDelta,
new ItemPath(ResourceType.F_CONNECTOR_CONFIGURATION, new QName(SchemaTestConstants.NS_ICFC, "producerBufferSize")),
100);
PrismAsserts.assertPropertyReplaceSimple(resourceDelta, ResourceType.F_SYNCHRONIZATION);
// Configuration properties changes
assertConfigurationPropertyChange(resourceDelta, "principal");
assertConfigurationPropertyChange(resourceDelta, "credentials");
Expand Down

0 comments on commit b9b6b4a

Please sign in to comment.