OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

sdo message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: ISSUE 44: ChangeSummary semantics


Title: ISSUE 44: ChangeSummary semantics

Hi Everyone,

I realize that I may getting too far ahead of the group here, but I want to write down my thoughts on this issue:  sooner or later we must address it in the TC.

When an object is moved from one container to another, so long as both are within the scope of the same ChangeSummary, the 2.1 spec allows for 2 possible interpretations, as far as the ChangeSummary is concerned.  The object may simply be moved (that is, the object itself is not changed, but the old container loses a reference to it), or the object may be deleted from the old container, and created in the new container.

I realize this will be a very sensitive issue: as soon as we decide one way or the other, we are breaking someone's backwards compatibility.  The trouble is, this is a pretty large whole to have been left open.  It makes it very hard to write a DAS that is independent of the SDO client, the DAS has to be programmed for different interpretations of the CS, and users that access the CS themselves never know what to expect.

To make things concrete, let's start with a code sample:

        DataObject root = DataFactory.INSTANCE.create("commonj.sdo","DataGraph");
            DataObject company = DataFactory.INSTANCE.create("example","Company");
        DataObject dept1 = company.createDataObject("department");
            DataObject dept2 = company.createDataObject("department");
            DataObject child = dept1.createDataObject("employee");

        root.getChangeSummary().beginLogging();
        dept2.getList("employee").add(child);
        root.getChangeSummary().endLoggin();

If we want to depict this as a "move", the following unit test would look like this:

        assertFalse(root.getChangeSummary().isModified(child));
        assertFalse(root.getChangeSummary().isCreated(child)); 
        assertFalse(root.getChangeSummary().isDeleted(child)); 
        assertTrue(root.getChangeSummary().isModified(dept1));
        assertTrue(root.getChangeSummary().isModified(dept2));

The XML looks like this

<DataGraph>
        <ChangeSummary>
                <Department ref="Company/Department[1]">
                        <Employee ref="Company/Department[2]/Employee[1]/>
                </Department>
                <Department ref="Company/Department[2]" sdox:unset="Employee"/>
        </ChangeSummary>
        <Company>
                        <Department>
                </Department>
                <Department>
                        <Employee/>
                </Department>
        </Company>
</DataGraph>

By contrast, if we we wanted to use create/delete, then the test would be something like this:

        assertFalse(root.getChangeSummary().isModified(child));
        assertTrue(root.getChangeSummary().isCreated(child));   // Is this correct?
        assertTrue(root.getChangeSummary().isDeleted(child));   // Is this correct?
        assertTrue(root.getChangeSummary().isModified(dept1));
        assertTrue(root.getChangeSummary().isModified(dept2));

And the XML would look like:

<DataGraph>
        <ChangeSummary deleted="ChangeSummary/Department[1]/Employee[1]" created="Company/Department[2]/Employee[1]">
                <Department ref="Company/Department[1]">
                        <Employee/>
                </Department>
                <Department ref="Company/Department[2]" sdox:unset="Employee"/>
        </ChangeSummary>
        <Company>
                        <Department>
                </Department>
                <Department>
                        <Employee/>
                </Department>
        </Company>
</DataGraph>

The result coming from deserializing the XML gives a different ChangeSummary than the one we had before serialization.  Namely, the following:

        DataObject root = XMLHelper.INSTANCE.load(…).getRootObject();
        DataObject company = root.getDataObject(0);
        DataObject dept1 = company.getList("department").get(0);
        DataObject dept2 = company.getList("department").get(1);
        DataObject child = dept2.getList("employee").get(0);

        assertFalse(root.getChangeSummary().isModified(child));
        assertTrue(root.getChangeSummary().isCreated(child));  
        assertFalse(root.getChangeSummary().isDeleted(child)); 
        assertTrue(root.getChangeSummary().isModified(dept1));
        assertTrue(root.getChangeSummary().isModified(dept2));

        DataObject deleted = root.getChangeSummary().getChangedObjects()…
        assertFalse(root.getChangeSummary().isCreated(child)); 
        assertTrue(root.getChangeSummary().isDeleted(child));  


I think these two behaviours are too diverent, we should really try to reconcile them.

Our implementation takes the "move" approach.  I would argue that this is the approach that obeys the "priciple of least surprise".  Being able to roundtrip to XML is also a major advantage.

I've heard two arguments for the create/delete approach:

1)  That containment "means" aggregation, and therefore that "moving" things between containers is nonsence.  What looks like a move is actually a delete/create.  The problem with this argument is that there is absolutely nothing else in the spec or the API that supports it.  For instance, if moving an object between two containers is impossible, then we should not allow it.  That is, the statement "dept2.getList("employee").add(child)" in the above code sample should throw an exception.  Actually, I'd be really happy to discuss this approach, and it certainly would clear up problems like "isCreated" and "isDeleted" both returning true.  On the other hand, this is a breaking change.

2)  That we should be able to calculate the change summary based on diff'ing the XML generated "before" and "after" the changes.  If we follow this argument to ist logical consequences, don't we also run into a bunch of other nasty problems.  Isn't it true that, from looking at the XML, you cannot distinguish any modification from a delete followed by a create?   And I never understood the role of XML is the calculation.  That's not to say that the CS cannot be calculated by diff'ing two graphs, but I am saying that the CS cannot necessarily be calculated by diff'ing the XML representation of the graphs.

Looking forward to an intersting discussion on this one!

Best Regards,
Ron



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]