XML support module allows text and tree editing of XML files, CSS2 editing etc.

Synchronization Issues

Overview

XML content can be modified by:
text
module text editor
tree
module tree editor
API
tree API (same as above)
file
external manipulation with file or DOM API manipulation
The modification can left the document valid or invalid.

Invalid content put extra requirement on tree editor because round-trip symetry is required.

Change Conflict

External modification can be in conflict with synchronized internal content. Therefore if a file change is detected a user is asked to replace internal content with modified one: If there are two versions while saving user is asked:

Representation

The representation means that actual state can be represented by several models. For example: swing.Document, tree.TreeDocument or FileObject content. A representation represents a model and tahes care of its state.

Its interface provides:

represents
does the representation represent given model?
update
update the representation by given change. Note that extenal representation typically do nothing since they are updated by save operation.
getChange
get change describtion of changed/modified
modified
is the representation that does not represent current change event modified?

Synchronizator

It manages relations between representation changes and updates. It is accessed using a synchronization controller (typically a DataObject). It has an entry method representationChanged(type[, context]).

It also holds set of currently loaded/managed representations. When a representation change event arrives the synchronizator responds with:

External Representation Pitfalls

The content can be changed externaly by a third party (not save action). In such case a dialog appears. A deletion case must be distigwished and used promted.

TODO it should not be called as result of Save action as org.openapi.loaders.... notifies it.

EditorSupport

The instance takes care about synchronizing swing.Document with external file. If external file changes and there is no Document modification it updates state of the Document. It also handles correctly bogus external modification caused by saving the Document by SaveCookie. However as there are two in memory representations (the Document and the Tree) then one in memory representation must be primary in respect of managing SaveCookie and external modification listening. [PENDING]

Sychronization Inputs (Changes)

Synchronizator itself does not listen at modifications. It must be explicitly excited by representationChanged() method. The method can be called from whenever thread. Typical stimuli are (use find: "representationChanged"):

Synchronization Related State Information

Sync state related fields
    boolean externalyModified;

    int JUST_SAVING = 2;
    int JUST_SYNCHRONIZING = 1;
    int NOP = 0;

    int syncOperation;
Sync state manipulation methods. All of these finish setting operation to NOP.

    init, reload {
        syncOperation = NOP;
        externalyModified = false;
    }

    treeChanged() {
        if syncOperation == SYNC return;
        syncOperation = SYNC;
    }

    textChanged() {
        if syncOperation == SYNC return;
        syncOperation = SYNC;
    }

    fileChanged() {
        if syncOperation == SAVING return;
        if externalyModified return;

        query user "update state"
        if "Let exist two versions" 
            externalyModified = true;
            return;

        .. update via text, because externa modifation can made it invalid ..
    }


    save() {
        syncOperation = SAVING;
        if externalyModified
            query user "whether overwrite or save as"

        .. save to particural location ..
        externalyModified = false;
    }


Indentation

Each getXMLString(deep, settings) could format current tree node. Formatting that apply just to current node consist of a formating prefix and substituted node value.