Skip to content

Commit

Permalink
Fixed serialization of "Anon" classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Mar 23, 2015
1 parent 65cbe8a commit 825193e
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 25 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,8 +21,10 @@
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;

import org.apache.commons.lang.Validate;

import java.io.Serializable;
import java.util.AbstractList;
import java.util.Collection;
import java.util.List;
Expand All @@ -35,10 +37,14 @@
*
* TODO: account for concurrent structural modifications using modCount property
*/
public abstract class PrismContainerArrayList<T extends Containerable> extends AbstractList<T> {
public abstract class PrismContainerArrayList<T extends Containerable> extends AbstractList<T> implements Serializable {

private PrismContainer<T> container;

// For deserialization
public PrismContainerArrayList() {
}

public PrismContainerArrayList(PrismContainer<T> container) {
Validate.notNull(container);
this.container = container;
Expand Down
Expand Up @@ -49,6 +49,9 @@ public class TestConstants {
public static final String USER_ACCOUNT_REF_2_OID = "2f9b9299-6f45-498f-aaaa-000000002222";
public static final String USER_ACCOUNT_REF_3_OID = "2f9b9299-6f45-498f-aaaa-000000003333";



public static final File RESOURCE_FILE = new File(TestConstants.COMMON_DIR, "resource-opendj.xml");
public static final String RESOURCE_OID = "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";
public static final String RESOURCE_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";

public static final File ROLE_FILE = new File(TestConstants.COMMON_DIR, "role.xml");
}
Expand Up @@ -76,11 +76,8 @@
*/
public class TestParseResource {

public static final File RESOURCE_FILE = new File(TestConstants.COMMON_DIR, "resource-opendj.xml");
public static final File RESOURCE_NO_XMLNS_FILE = new File(TestConstants.COMMON_DIR, "resource-opendj-no-xmlns.xml");
public static final File RESOURCE_NO_XMLNS_FILE = new File(TestConstants.COMMON_DIR, "resource-opendj-no-xmlns.xml");
public static final File RESOURCE_SIMPLE_FILE = new File(TestConstants.COMMON_DIR, "resource-opendj-simple.xml");
private static final String RESOURCE_OID = "ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";
private static final String RESOURCE_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-3d4f02d3ffff";

@BeforeSuite
public void setup() throws SchemaException, SAXException, IOException {
Expand All @@ -97,7 +94,7 @@ public void testParseResourceFile() throws Exception {
PrismContext prismContext = PrismTestUtil.getPrismContext();

// WHEN
PrismObject<ResourceType> resource = prismContext.parseObject(RESOURCE_FILE);
PrismObject<ResourceType> resource = prismContext.parseObject(TestConstants.RESOURCE_FILE);

// THEN
System.out.println("Parsed resource:");
Expand Down Expand Up @@ -133,7 +130,7 @@ public void testParseResourceDom() throws Exception {

// WHEN
DomParser parserDom = prismContext.getParserDom();
XNode xnode = parserDom.parse(RESOURCE_FILE);
XNode xnode = parserDom.parse(TestConstants.RESOURCE_FILE);
PrismObject<ResourceType> resource = prismContext.getXnodeProcessor().parseObject(xnode);

// THEN
Expand Down Expand Up @@ -173,7 +170,7 @@ public void testPrismParseJaxb() throws Exception {
JaxbTestUtil jaxbProcessor = JaxbTestUtil.getInstance();

// WHEN
ResourceType resourceType = jaxbProcessor.unmarshalObject(RESOURCE_FILE, ResourceType.class);
ResourceType resourceType = jaxbProcessor.unmarshalObject(TestConstants.RESOURCE_FILE, ResourceType.class);

// THEN
// HACK: the JAXB parsing methods do not support filter yet, so avoid checking for it
Expand Down Expand Up @@ -211,7 +208,7 @@ public void testPrismParseJaxbObjectType() throws JAXBException, SchemaException
JaxbTestUtil jaxbProcessor = JaxbTestUtil.getInstance();

// WHEN
ObjectType resourceType = jaxbProcessor.unmarshalObject(RESOURCE_FILE, ObjectType.class);
ObjectType resourceType = jaxbProcessor.unmarshalObject(TestConstants.RESOURCE_FILE, ObjectType.class);

// THEN
// HACK: the JAXB parsing methods do not support filter yet, so avoid checking for it
Expand All @@ -231,7 +228,7 @@ public void testPrismParseJaxbElement() throws JAXBException, SchemaException, S
JaxbTestUtil jaxbProcessor = JaxbTestUtil.getInstance();

// WHEN
JAXBElement<ResourceType> jaxbElement = jaxbProcessor.unmarshalElement(RESOURCE_FILE, ResourceType.class);
JAXBElement<ResourceType> jaxbElement = jaxbProcessor.unmarshalElement(TestConstants.RESOURCE_FILE, ResourceType.class);
ResourceType resourceType = jaxbElement.getValue();

// THEN
Expand All @@ -252,7 +249,7 @@ public void testPrismParseJaxbElementObjectType() throws JAXBException, SchemaEx
JaxbTestUtil jaxbProcessor = JaxbTestUtil.getInstance();

// WHEN
JAXBElement<ObjectType> jaxbElement = jaxbProcessor.unmarshalElement(RESOURCE_FILE, ObjectType.class);
JAXBElement<ObjectType> jaxbElement = jaxbProcessor.unmarshalElement(TestConstants.RESOURCE_FILE, ObjectType.class);
ObjectType resourceType = jaxbElement.getValue();

// THEN
Expand All @@ -267,7 +264,7 @@ public void testParseResourceRoundtrip() throws Exception {
// GIVEN
PrismContext prismContext = PrismTestUtil.getPrismContext();

PrismObject<ResourceType> resource = prismContext.parseObject(RESOURCE_FILE);
PrismObject<ResourceType> resource = prismContext.parseObject(TestConstants.RESOURCE_FILE);

System.out.println("Parsed resource:");
System.out.println(resource.debugDump());
Expand Down Expand Up @@ -371,7 +368,7 @@ public void testSchemaRoundtrip() throws Exception {
// GIVEN
PrismContext prismContext = PrismTestUtil.getPrismContext();

PrismObject<ResourceType> resource = prismContext.parseObject(RESOURCE_FILE);
PrismObject<ResourceType> resource = prismContext.parseObject(TestConstants.RESOURCE_FILE);

assertResource(resource, true, false, false);

Expand Down Expand Up @@ -426,7 +423,7 @@ private void assertResourcePrism(PrismObject<ResourceType> resource, boolean isS

PrismContext prismContext = PrismTestUtil.getPrismContext();

assertEquals("Wrong oid (prism)", RESOURCE_OID, resource.getOid());
assertEquals("Wrong oid (prism)", TestConstants.RESOURCE_OID, resource.getOid());
// assertEquals("Wrong version", "42", resource.getVersion());
PrismObjectDefinition<ResourceType> resourceDefinition = resource.getDefinition();
assertNotNull("No resource definition", resourceDefinition);
Expand All @@ -440,7 +437,7 @@ private void assertResourcePrism(PrismObject<ResourceType> resource, boolean isS
assertPropertyDefinition(resource, "name", PolyStringType.COMPLEX_TYPE, 0, 1);

if (!isSimple) {
assertPropertyValue(resource, "namespace", RESOURCE_NAMESPACE);
assertPropertyValue(resource, "namespace", TestConstants.RESOURCE_NAMESPACE);
assertPropertyDefinition(resource, "namespace", DOMUtil.XSD_ANYURI, 0, 1);
}

Expand Down Expand Up @@ -524,9 +521,9 @@ private void assertResourcePrism(PrismObject<ResourceType> resource, boolean isS
}

private void assertResourceJaxb(ResourceType resourceType, boolean isSimple) throws SchemaException {
assertEquals("Wrong oid (JAXB)", RESOURCE_OID, resourceType.getOid());
assertEquals("Wrong oid (JAXB)", TestConstants.RESOURCE_OID, resourceType.getOid());
assertEquals("Wrong name (JAXB)", PrismTestUtil.createPolyStringType("Embedded Test OpenDJ"), resourceType.getName());
String expectedNamespace = RESOURCE_NAMESPACE;
String expectedNamespace = TestConstants.RESOURCE_NAMESPACE;
if (isSimple) {
expectedNamespace = MidPointConstants.NS_RI;
}
Expand Down
@@ -0,0 +1,140 @@
/*
* Copyright (c) 2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.schema;

import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.SerializationUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.util.List;


/**
* @author semancik
*
*/
public class TestSerialization {



@BeforeSuite
public void setup() throws SchemaException, SAXException, IOException {
PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX);
PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY);
}


@Test
public void testSerializeResource() throws Exception {
System.out.println("===[ testSerializeResource ]===");

serializationRoundTrip(TestConstants.RESOURCE_FILE);
}

@Test
public void testSerializeUser() throws Exception {
System.out.println("===[ testSerializeUser ]===");

serializationRoundTrip(TestConstants.USER_FILE);
}

@Test
public void testSerializeRole() throws Exception {
System.out.println("===[ testSerializeRole ]===");

PrismContext prismContext = PrismTestUtil.getPrismContext();

PrismObject<RoleType> parsedObject = prismContext.parseObject(TestConstants.ROLE_FILE);

System.out.println("Parsed object:");
System.out.println(parsedObject.debugDump());

RoleType parsedRoleType = parsedObject.asObjectable();
PolicyConstraintsType policyConstraints = parsedRoleType.getPolicyConstraints();
List<MultiplicityPolicyConstraintType> minAssignees = policyConstraints.getMinAssignees();
minAssignees.iterator().next();

// WHEN
serializationRoundTripPrismObject(parsedObject);
serializationRoundTripObjectType(parsedRoleType);

// WHEN
String serializedMinAssignees = SerializationUtil.toString(minAssignees);
List<MultiplicityPolicyConstraintType> deserializedMinAssignees = SerializationUtil.fromString(serializedMinAssignees);
assertTrue("minAssignees mismatch: expected "+minAssignees+", was "+deserializedMinAssignees, MiscUtil.listEquals(minAssignees, deserializedMinAssignees));
}

private <O extends ObjectType> void serializationRoundTrip(File file) throws Exception {
PrismContext prismContext = PrismTestUtil.getPrismContext();

PrismObject<O> parsedObject = prismContext.parseObject(file);

System.out.println("Parsed object:");
System.out.println(parsedObject.debugDump());

serializationRoundTripPrismObject(parsedObject);
serializationRoundTripObjectType(parsedObject.asObjectable());
}

private <O extends ObjectType> void serializationRoundTripPrismObject(PrismObject<O> parsedObject) throws Exception {

// WHEN
String serializedObject = SerializationUtil.toString(parsedObject);

// THEN
PrismObject<O> deserializedObject = SerializationUtil.fromString(serializedObject);

System.out.println("Deserialized object (PrismObject):");
System.out.println(deserializedObject.debugDump());

ObjectDelta<O> diff = parsedObject.diff(deserializedObject);
assertTrue("Something changed in serialization of "+parsedObject+" (PrismObject): "+diff, diff.isEmpty());
}

private <O extends ObjectType> void serializationRoundTripObjectType(O parsedObject) throws Exception {

// WHEN
String serializedObject = SerializationUtil.toString(parsedObject);

// THEN
O deserializedObject = SerializationUtil.fromString(serializedObject);

System.out.println("Deserialized object (ObjectType):");
System.out.println(deserializedObject.asPrismObject().debugDump());

ObjectDelta<O> diff = parsedObject.asPrismObject().diff(deserializedObject.asPrismObject());
assertTrue("Something changed in serializetion of "+parsedObject+" (ObjectType): "+diff, diff.isEmpty());
}

}
13 changes: 13 additions & 0 deletions infra/schema/src/test/resources/common/role.xml
Expand Up @@ -27,4 +27,17 @@
<code>midpoint.oid2ort(user.getOid())</code>
</script>
</approverExpression>

<policyConstraints>
<minAssignees>
<enforcement>report</enforcement>
<multiplicity>2</multiplicity>
</minAssignees>
<minAssignees>
<multiplicity>1</multiplicity>
</minAssignees>
<maxAssignees>
<multiplicity>unbounded</multiplicity>
</maxAssignees>
</policyConstraints>
</role>
1 change: 1 addition & 0 deletions infra/schema/testng.xml
Expand Up @@ -44,6 +44,7 @@
<class name="com.evolveum.midpoint.schema.TestDynamicSchema"/>
<class name="com.evolveum.midpoint.schema.TestJsonParsing"/>
<class name="com.evolveum.midpoint.schema.TestSchemaDelta"/>
<class name="com.evolveum.midpoint.schema.TestSerialization"/>
<class name="com.evolveum.midpoint.schema.util.SelectorOptionsTest"/>
</classes>
</test>
Expand Down
18 changes: 18 additions & 0 deletions infra/util/src/main/java/com/evolveum/midpoint/util/MiscUtil.java
Expand Up @@ -82,6 +82,24 @@ public static <T> Collection<? extends T> unionExtends(Collection<? extends T>..
return resultSet;
}

public static <T> boolean listEquals(List<T> a, List<T> b) {
if (a == null && b == null) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a.size() != b.size()) {
return false;
}
for (int i = 0; i < a.size(); i++) {
if (!a.get(i).equals(b.get(i))) {
return false;
}
}
return true;
}

public static boolean unorderedCollectionEquals(Collection a, Collection b) {
Comparator<?> comparator = new Comparator<Object>() {
@Override
Expand Down
Expand Up @@ -35,15 +35,15 @@
*/
public class SerializationUtil {

public static Object fromString(String string) throws IOException, ClassNotFoundException {
public static <T> T fromString(String string) throws IOException, ClassNotFoundException {
byte[] data = Base64.decodeBase64(string);
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data));
Object object = objectInputStream.readObject();
objectInputStream.close();
return object;
return (T)object;
}

public static String toString(Serializable object) throws IOException {
public static String toString(Object object) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(object);
Expand Down

0 comments on commit 825193e

Please sign in to comment.