Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » XML (Structured) Text editor synchronized with EMF view
XML (Structured) Text editor synchronized with EMF view [message #414478] Thu, 08 November 2007 10:38 Go to next message
Eclipse User
Originally posted by: mcostes.hotmail.com

Hi to all,

First excuse my bad English ;-)

I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML editor plugin.

From XSD schema, I have generated the Ecore model and from genmodel the
model code, edit code and editor code.

The createPages() method of editor class creates a page for the EMF tree
viewer (named viewerPane).

I've added to the editor a StructuredTextEditor by adding this snippet
code in createPages() method of editor class:

try {
StructuredTextEditor xmlSource = new StructuredTextEditor();
int index = addPage(xmlSource, getEditorInput());
setPageText(index, xmlSource.getTitle());
} catch (PartInitException pie) {}

I would like the XML Source to be synchronized with the EMF tree.
Actually when a modification occurs on EMF tree, XML view is also
updated with this modification ... but on the contrary a modification on
XML source doesn't occur on EMF tree.

Is there a simple way for implement this?

I've heard about SSE, EMF2DOM adapters ... but I've not found any sample
or snippet code for doing that.

Thanks a lot for your help

Marie
Re: XML (Structured) Text editor synchronized with EMF view [message #414485 is a reply to message #414478] Thu, 08 November 2007 12:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25943
Registered: July 2009
Senior Member
Marie,

Comments below.

Marie C wrote:
> Hi to all,
>
> First excuse my bad English ;-)
As long as you'll excuse my exclusive use of English.
>
> I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML editor
> plugin.
>
> From XSD schema, I have generated the Ecore model and from genmodel
> the model code, edit code and editor code.
>
> The createPages() method of editor class creates a page for the EMF
> tree viewer (named viewerPane).
>
> I've added to the editor a StructuredTextEditor by adding this snippet
> code in createPages() method of editor class:
>
> try {
> StructuredTextEditor xmlSource = new StructuredTextEditor();
> int index = addPage(xmlSource, getEditorInput());
> setPageText(index, xmlSource.getTitle());
> } catch (PartInitException pie) {}
>
> I would like the XML Source to be synchronized with the EMF tree.
> Actually when a modification occurs on EMF tree, XML view is also
> updated with this modification ... but on the contrary a modification
> on XML source doesn't occur on EMF tree.
>
> Is there a simple way for implement this?
>
> I've heard about SSE, EMF2DOM adapters ... but I've not found any
> sample or snippet code for doing that.
It's a pretty tricky problem that I wish we had a good reusable solution
for already. All I can suggest that would be fairly easy would be kind
of brute force solutions. Using XMLResource.save(Document document,
Map<?, ?> options, DOMHandler handler) with a handler you could convert
a model to a SSE DOM maintaining a mapping from the EObject to the DOM.
When the model changes, you could repeat that process. If the DOM
changes, you could unload the EMF resource and use void load(Node
node, Map<?, ?> options). It's very crude but that's the best I can
suggest. I imagine one could do some very nice fine grained integration
to support an EMF2DOM adapter automatically given the extended metadata
annotations on the model, but I can't point you at any source code for
that. It would make a great EMFT component...
>
> Thanks a lot for your help
>
> Marie
Re: XML (Structured) Text editor synchronized with EMF view [message #414539 is a reply to message #414485] Mon, 12 November 2007 06:13 Go to previous messageGo to next message
Eclipse User
Originally posted by: mcostes.hotmail.com

Thanks a lot Ed for your answer.

I understand your explanation.

However, how modify the editing domain resource ?

For example, with the following code, resource is never modified.

// xmlSource is StructuredTextEditor
IDocument doc =
xmlSource.getDocumentProvider().getDocument(getEditorInput() );
....
XMLResource initialResource =
(XMLResource)editingDomain.getResourceSet().getResources().g et(0);

initialResource.load(new ByteArrayInputStream(doc.get().getBytes()), null);

// display the content of the resource in sysout
initialResource.save(System.out, Collections.EMPTY_MAP);



Thanks for your help

Marie

Ed Merks a écrit :
> Marie,
>
> Comments below.
>
> Marie C wrote:
>> Hi to all,
>>
>> First excuse my bad English ;-)
> As long as you'll excuse my exclusive use of English.
>>
>> I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML editor
>> plugin.
>>
>> From XSD schema, I have generated the Ecore model and from genmodel
>> the model code, edit code and editor code.
>>
>> The createPages() method of editor class creates a page for the EMF
>> tree viewer (named viewerPane).
>>
>> I've added to the editor a StructuredTextEditor by adding this snippet
>> code in createPages() method of editor class:
>>
>> try { StructuredTextEditor xmlSource = new
>> StructuredTextEditor(); int index = addPage(xmlSource,
>> getEditorInput());
>> setPageText(index, xmlSource.getTitle());
>> } catch (PartInitException pie) {}
>>
>> I would like the XML Source to be synchronized with the EMF tree.
>> Actually when a modification occurs on EMF tree, XML view is also
>> updated with this modification ... but on the contrary a modification
>> on XML source doesn't occur on EMF tree.
>>
>> Is there a simple way for implement this?
>>
>> I've heard about SSE, EMF2DOM adapters ... but I've not found any
>> sample or snippet code for doing that.
> It's a pretty tricky problem that I wish we had a good reusable solution
> for already. All I can suggest that would be fairly easy would be kind
> of brute force solutions. Using XMLResource.save(Document document,
> Map<?, ?> options, DOMHandler handler) with a handler you could convert
> a model to a SSE DOM maintaining a mapping from the EObject to the DOM.
> When the model changes, you could repeat that process. If the DOM
> changes, you could unload the EMF resource and use void load(Node
> node, Map<?, ?> options). It's very crude but that's the best I can
> suggest. I imagine one could do some very nice fine grained integration
> to support an EMF2DOM adapter automatically given the extended metadata
> annotations on the model, but I can't point you at any source code for
> that. It would make a great EMFT component...
>>
>> Thanks a lot for your help
>>
>> Marie
Re: XML (Structured) Text editor synchronized with EMF view [message #414540 is a reply to message #414539] Mon, 12 November 2007 07:17 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25943
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------060401070503040402090408
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Marie,

I suggested using this load method to load directly from the DOM that is
supported by SSE:

/**
* Loads the resource from the DOM node, either an Element or
Document, using the specified options.
* <p>
* This method assumes that no namespace fixup needs to be done.
* To process comments and CDATA section nodes, please set
XMLResource.OPTION_USE_LEXICAL_HANDLER option to Boolean.TRUE.
* </p>
* @param node DOM Element or Document node.
* @param options the load options.
* @see #save(Document, Map, DOMHandler)
* @since 2.1.0
*/
void load(Node node, Map<?, ?> options) throws IOException;

You can look at the source code for the XSD model's sample XSDEditor to
see a very crude way in which we sync up the source and the resource.
You can see that whenever a command is executed on the model,
handleStructuredModelChange is called to update the document with the
new serialized version. You'd want to use to serialize directly to the
SSE DOM.

/**
* Create a DOM tree representing contents of this resource.
* @param document an empty {@link org.w3c.dom.Document} to use or
null. If no document is specified, the
* new {@link org.w3c.dom.Document} will be created using JAXP API.
* @param options the "save" options
* @param handler the {@link org.eclipse.emf.ecore.xmi.DOMHandler}
to record mappings or null.
* If no DOMHandler is passed, the default DOMHandler will be created.
* @return the {@link org.w3c.dom.Document}. In the case the
document is specified as a parameter,
* the returned document is the same as the one specified,
otherwise the newly created document is returned.
* @since 2.1.0
*/
Document save(Document document, Map<?, ?> options, DOMHandler
handler);

In createSourcePage you'll see we hook up a listener to the document so
when it changes, handleDocumentChange is called to update the document.
In your case, you'd call the above load method again.


Marie C wrote:
> Thanks a lot Ed for your answer.
>
> I understand your explanation.
>
> However, how modify the editing domain resource ?
>
> For example, with the following code, resource is never modified.
>
> // xmlSource is StructuredTextEditor
> IDocument doc =
> xmlSource.getDocumentProvider().getDocument(getEditorInput() );
> ....
> XMLResource initialResource =
> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>
> initialResource.load(new ByteArrayInputStream(doc.get().getBytes()),
> null);
>
> // display the content of the resource in sysout
> initialResource.save(System.out, Collections.EMPTY_MAP);
>
>
>
> Thanks for your help
>
> Marie
>
> Ed Merks a
Re: XML (Structured) Text editor synchronized with EMF view [message #414712 is a reply to message #414540] Mon, 19 November 2007 08:10 Go to previous messageGo to next message
Eclipse User
Originally posted by: mcostes.hotmail.com

Many thanks Ed !!
It works for me.

/**
*
*/
protected void handleStructuredModelChange() {
try {
// get resource
XMLResource resource =
(XMLResource)editingDomain.getResourceSet().getResources().g et(0);

// save it in DOM
Document xmlDom = resource.save(null, Collections.EMPTY_MAP, null);

// load it
resource.load(xmlDom, Collections.EMPTY_MAP);
} catch (Exception e) {}
}

/**
*
*/
protected void handleDocumentChange() {
try {
IDocument document =
xmlEditor.getDocumentProvider().getDocument(xmlEditor.getEdi torInput());

// get resource
XMLResource xmlResource =
(XMLResource)editingDomain.getResourceSet().getResources().g et(0);

// unload resource
if (xmlResource.isLoaded()) {
xmlResource.unload();
}

// construct new DOM
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();
Document newDom = builder.parse(new InputSource(new
StringReader(document.get())));

// load resource
xmlResource.load(newDom, Collections.EMPTY_MAP);
} catch (Exception e) {}



Marie




Ed Merks a écrit :
> Marie,
>
> I suggested using this load method to load directly from the DOM that is
> supported by SSE:
>
> /**
> * Loads the resource from the DOM node, either an Element or
> Document, using the specified options.
> * <p>
> * This method assumes that no namespace fixup needs to be done.
> * To process comments and CDATA section nodes, please set
> XMLResource.OPTION_USE_LEXICAL_HANDLER option to Boolean.TRUE.
> * </p>
> * @param node DOM Element or Document node.
> * @param options the load options.
> * @see #save(Document, Map, DOMHandler)
> * @since 2.1.0
> */
> void load(Node node, Map<?, ?> options) throws IOException;
>
> You can look at the source code for the XSD model's sample XSDEditor to
> see a very crude way in which we sync up the source and the resource.
> You can see that whenever a command is executed on the model,
> handleStructuredModelChange is called to update the document with the
> new serialized version. You'd want to use to serialize directly to the
> SSE DOM.
>
> /**
> * Create a DOM tree representing contents of this resource.
> * @param document an empty {@link org.w3c.dom.Document} to use or
> null. If no document is specified, the
> * new {@link org.w3c.dom.Document} will be created using JAXP API.
> * @param options the "save" options
> * @param handler the {@link org.eclipse.emf.ecore.xmi.DOMHandler}
> to record mappings or null.
> * If no DOMHandler is passed, the default DOMHandler will be created.
> * @return the {@link org.w3c.dom.Document}. In the case the
> document is specified as a parameter,
> * the returned document is the same as the one specified,
> otherwise the newly created document is returned.
> * @since 2.1.0
> */
> Document save(Document document, Map<?, ?> options, DOMHandler
> handler);
>
> In createSourcePage you'll see we hook up a listener to the document so
> when it changes, handleDocumentChange is called to update the document.
> In your case, you'd call the above load method again.
>
>
> Marie C wrote:
>> Thanks a lot Ed for your answer.
>>
>> I understand your explanation.
>>
>> However, how modify the editing domain resource ?
>>
>> For example, with the following code, resource is never modified.
>>
>> // xmlSource is StructuredTextEditor
>> IDocument doc =
>> xmlSource.getDocumentProvider().getDocument(getEditorInput() );
>> ....
>> XMLResource initialResource =
>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>
>> initialResource.load(new ByteArrayInputStream(doc.get().getBytes()),
>> null);
>>
>> // display the content of the resource in sysout
>> initialResource.save(System.out, Collections.EMPTY_MAP);
>>
>>
>>
>> Thanks for your help
>>
>> Marie
>>
>> Ed Merks a écrit :
>>> Marie,
>>>
>>> Comments below.
>>>
>>> Marie C wrote:
>>>> Hi to all,
>>>>
>>>> First excuse my bad English ;-)
>>> As long as you'll excuse my exclusive use of English.
>>>>
>>>> I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML editor
>>>> plugin.
>>>>
>>>> From XSD schema, I have generated the Ecore model and from genmodel
>>>> the model code, edit code and editor code.
>>>>
>>>> The createPages() method of editor class creates a page for the EMF
>>>> tree viewer (named viewerPane).
>>>>
>>>> I've added to the editor a StructuredTextEditor by adding this
>>>> snippet code in createPages() method of editor class:
>>>>
>>>> try { StructuredTextEditor xmlSource = new
>>>> StructuredTextEditor(); int index = addPage(xmlSource,
>>>> getEditorInput());
>>>> setPageText(index, xmlSource.getTitle());
>>>> } catch (PartInitException pie) {}
>>>>
>>>> I would like the XML Source to be synchronized with the EMF tree.
>>>> Actually when a modification occurs on EMF tree, XML view is also
>>>> updated with this modification ... but on the contrary a
>>>> modification on XML source doesn't occur on EMF tree.
>>>>
>>>> Is there a simple way for implement this?
>>>>
>>>> I've heard about SSE, EMF2DOM adapters ... but I've not found any
>>>> sample or snippet code for doing that.
>>> It's a pretty tricky problem that I wish we had a good reusable
>>> solution for already. All I can suggest that would be fairly easy
>>> would be kind of brute force solutions. Using
>>> XMLResource.save(Document document, Map<?, ?> options, DOMHandler
>>> handler) with a handler you could convert a model to a SSE DOM
>>> maintaining a mapping from the EObject to the DOM. When the model
>>> changes, you could repeat that process. If the DOM changes, you
>>> could unload the EMF resource and use void load(Node node, Map<?,
>>> ?> options). It's very crude but that's the best I can suggest. I
>>> imagine one could do some very nice fine grained integration to
>>> support an EMF2DOM adapter automatically given the extended metadata
>>> annotations on the model, but I can't point you at any source code
>>> for that. It would make a great EMFT component...
>>>>
>>>> Thanks a lot for your help
>>>>
>>>> Marie
>
Re: XML (Structured) Text editor synchronized with EMF view [message #414713 is a reply to message #414712] Mon, 19 November 2007 15:13 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25943
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------050508030408000305030005
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Marie,

If you has a String rather than a DOM to start with, this would perform
significantly better:

resource.load(new InputSource(new StringReader(document.get())),
Collections.EMPTY_MAP);


Marie C wrote:
> Many thanks Ed !!
> It works for me.
>
> /**
> *
> */
> protected void handleStructuredModelChange() {
> try {
> // get resource
> XMLResource resource =
> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>
> // save it in DOM
> Document xmlDom = resource.save(null, Collections.EMPTY_MAP, null);
>
> // load it
> resource.load(xmlDom, Collections.EMPTY_MAP);
> } catch (Exception e) {}
> }
>
> /**
> *
> */
> protected void handleDocumentChange() {
> try {
> IDocument document =
> xmlEditor.getDocumentProvider().getDocument(xmlEditor.getEdi torInput());
>
> // get resource
> XMLResource xmlResource =
> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>
> // unload resource
> if (xmlResource.isLoaded()) {
> xmlResource.unload();
> }
>
> // construct new DOM
> DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
> DocumentBuilder builder = factory.newDocumentBuilder();
> Document newDom = builder.parse(new InputSource(new
> StringReader(document.get())));
>
> // load resource
> xmlResource.load(newDom, Collections.EMPTY_MAP);
> } catch (Exception e) {}
>
>
>
> Marie
>
>
>
>
> Ed Merks a
Re: XML (Structured) Text editor synchronized with EMF view [message #414826 is a reply to message #414713] Fri, 23 November 2007 06:07 Go to previous messageGo to next message
Eclipse User
Originally posted by: mcostes.hotmail.com

Thanks Ed for your suggestion.

However, I’ve another problem in the doSave() method when I’m trying to
unload resource. A SWTException (Invalid thread access) occurs.

This is my snippet code :


for (Iterator i =
editingDomain.getResourceSet().getResources().iterator(); i.hasNext(); ) {
XMLResource resource = (XMLResource)i.next();
if ((first || !resource.getContents().isEmpty() ||
isPersisted(resource)) && !editingDomain.isReadOnly(resource)) {
try {
// unload resource
if (resource.isLoaded()) {
resource.unload();
}

savedResources.add(resource);
resource.load(new InputSource(new
StringReader(getXmlDocument().get())), Collections.EMPTY_MAP);
resource.save(Collections.EMPTY_MAP);
}
catch (Exception exception) {
resourceToDiagnosticMap.put(resource,
analyzeResourceProblems(resource, exception));
}
first = false;
}
}


Is it normal ?
Thanks for your help

Marie

Ed Merks a écrit :
> Marie,
>
> If you has a String rather than a DOM to start with, this would perform
> significantly better:
>
> resource.load(new InputSource(new StringReader(document.get())),
> Collections.EMPTY_MAP);
>
>
> Marie C wrote:
>> Many thanks Ed !!
>> It works for me.
>>
>> /**
>> *
>> */
>> protected void handleStructuredModelChange() {
>> try {
>> // get resource
>> XMLResource resource =
>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>
>> // save it in DOM
>> Document xmlDom = resource.save(null, Collections.EMPTY_MAP, null);
>>
>> // load it
>> resource.load(xmlDom, Collections.EMPTY_MAP);
>> } catch (Exception e) {}
>> }
>>
>> /**
>> *
>> */
>> protected void handleDocumentChange() {
>> try {
>> IDocument document =
>> xmlEditor.getDocumentProvider().getDocument(xmlEditor.getEdi torInput());
>>
>> // get resource
>> XMLResource xmlResource =
>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>
>> // unload resource
>> if (xmlResource.isLoaded()) {
>> xmlResource.unload();
>> }
>>
>> // construct new DOM
>> DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
>> DocumentBuilder builder = factory.newDocumentBuilder();
>> Document newDom = builder.parse(new InputSource(new
>> StringReader(document.get())));
>>
>> // load resource
>> xmlResource.load(newDom, Collections.EMPTY_MAP);
>> } catch (Exception e) {}
>>
>>
>>
>> Marie
>>
>>
>>
>>
>> Ed Merks a écrit :
>>> Marie,
>>>
>>> I suggested using this load method to load directly from the DOM that
>>> is supported by SSE:
>>>
>>> /**
>>> * Loads the resource from the DOM node, either an Element or
>>> Document, using the specified options.
>>> * <p>
>>> * This method assumes that no namespace fixup needs to be done.
>>> * To process comments and CDATA section nodes, please set
>>> XMLResource.OPTION_USE_LEXICAL_HANDLER option to Boolean.TRUE.
>>> * </p>
>>> * @param node DOM Element or Document node.
>>> * @param options the load options.
>>> * @see #save(Document, Map, DOMHandler)
>>> * @since 2.1.0
>>> */
>>> void load(Node node, Map<?, ?> options) throws IOException;
>>>
>>> You can look at the source code for the XSD model's sample XSDEditor
>>> to see a very crude way in which we sync up the source and the
>>> resource. You can see that whenever a command is executed on the
>>> model, handleStructuredModelChange is called to update the document
>>> with the new serialized version. You'd want to use to serialize
>>> directly to the SSE DOM.
>>>
>>> /**
>>> * Create a DOM tree representing contents of this resource.
>>> * @param document an empty {@link org.w3c.dom.Document} to use or
>>> null. If no document is specified, the
>>> * new {@link org.w3c.dom.Document} will be created using JAXP
>>> API.
>>> * @param options the "save" options
>>> * @param handler the {@link org.eclipse.emf.ecore.xmi.DOMHandler}
>>> to record mappings or null.
>>> * If no DOMHandler is passed, the default DOMHandler will be
>>> created.
>>> * @return the {@link org.w3c.dom.Document}. In the case the
>>> document is specified as a parameter,
>>> * the returned document is the same as the one specified,
>>> otherwise the newly created document is returned.
>>> * @since 2.1.0
>>> */
>>> Document save(Document document, Map<?, ?> options, DOMHandler
>>> handler);
>>>
>>> In createSourcePage you'll see we hook up a listener to the document
>>> so when it changes, handleDocumentChange is called to update the
>>> document. In your case, you'd call the above load method again.
>>>
>>>
>>> Marie C wrote:
>>>> Thanks a lot Ed for your answer.
>>>>
>>>> I understand your explanation.
>>>>
>>>> However, how modify the editing domain resource ?
>>>>
>>>> For example, with the following code, resource is never modified.
>>>>
>>>> // xmlSource is StructuredTextEditor
>>>> IDocument doc =
>>>> xmlSource.getDocumentProvider().getDocument(getEditorInput() );
>>>> ....
>>>> XMLResource initialResource =
>>>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>>>
>>>> initialResource.load(new ByteArrayInputStream(doc.get().getBytes()),
>>>> null);
>>>>
>>>> // display the content of the resource in sysout
>>>> initialResource.save(System.out, Collections.EMPTY_MAP);
>>>>
>>>>
>>>>
>>>> Thanks for your help
>>>>
>>>> Marie
>>>>
>>>> Ed Merks a écrit :
>>>>> Marie,
>>>>>
>>>>> Comments below.
>>>>>
>>>>> Marie C wrote:
>>>>>> Hi to all,
>>>>>>
>>>>>> First excuse my bad English ;-)
>>>>> As long as you'll excuse my exclusive use of English.
>>>>>>
>>>>>> I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML
>>>>>> editor plugin.
>>>>>>
>>>>>> From XSD schema, I have generated the Ecore model and from
>>>>>> genmodel the model code, edit code and editor code.
>>>>>>
>>>>>> The createPages() method of editor class creates a page for the
>>>>>> EMF tree viewer (named viewerPane).
>>>>>>
>>>>>> I've added to the editor a StructuredTextEditor by adding this
>>>>>> snippet code in createPages() method of editor class:
>>>>>>
>>>>>> try { StructuredTextEditor xmlSource = new
>>>>>> StructuredTextEditor(); int index = addPage(xmlSource,
>>>>>> getEditorInput());
>>>>>> setPageText(index, xmlSource.getTitle());
>>>>>> } catch (PartInitException pie) {}
>>>>>>
>>>>>> I would like the XML Source to be synchronized with the EMF tree.
>>>>>> Actually when a modification occurs on EMF tree, XML view is also
>>>>>> updated with this modification ... but on the contrary a
>>>>>> modification on XML source doesn't occur on EMF tree.
>>>>>>
>>>>>> Is there a simple way for implement this?
>>>>>>
>>>>>> I've heard about SSE, EMF2DOM adapters ... but I've not found any
>>>>>> sample or snippet code for doing that.
>>>>> It's a pretty tricky problem that I wish we had a good reusable
>>>>> solution for already. All I can suggest that would be fairly easy
>>>>> would be kind of brute force solutions. Using
>>>>> XMLResource.save(Document document, Map<?, ?> options, DOMHandler
>>>>> handler) with a handler you could convert a model to a SSE DOM
>>>>> maintaining a mapping from the EObject to the DOM. When the model
>>>>> changes, you could repeat that process. If the DOM changes, you
>>>>> could unload the EMF resource and use void load(Node node, Map<?,
>>>>> ?> options). It's very crude but that's the best I can suggest. I
>>>>> imagine one could do some very nice fine grained integration to
>>>>> support an EMF2DOM adapter automatically given the extended
>>>>> metadata annotations on the model, but I can't point you at any
>>>>> source code for that. It would make a great EMFT component...
>>>>>>
>>>>>> Thanks a lot for your help
>>>>>>
>>>>>> Marie
>>>
>
Re: XML (Structured) Text editor synchronized with EMF view [message #414827 is a reply to message #414826] Fri, 23 November 2007 07:12 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25943
Registered: July 2009
Senior Member
Marie,

I don't see anything directly in this code that accesses SWT widgets.
But you do need to keep in mind that you can only access widgets on the
GUI thread. This type of approach can be used to ensure that something
being processed on a background thread that needs to access the SWT does
it using the proper thread:

getSite().getShell().getDisplay().asyncExec
(new Runnable()
{
public void run()
{
// Do something on the GUI thread.
}
});



Marie C wrote:
> Thanks Ed for your suggestion.
>
> However, I’ve another problem in the doSave() method when I’m trying
> to unload resource. A SWTException (Invalid thread access) occurs.
>
> This is my snippet code :
>
>
> for (Iterator i =
> editingDomain.getResourceSet().getResources().iterator(); i.hasNext();
> ) {
> XMLResource resource = (XMLResource)i.next();
> if ((first || !resource.getContents().isEmpty() ||
> isPersisted(resource)) && !editingDomain.isReadOnly(resource)) {
> try {
> // unload resource
> if (resource.isLoaded()) {
> resource.unload();
> }
>
> savedResources.add(resource);
> resource.load(new InputSource(new
> StringReader(getXmlDocument().get())),
> Collections.EMPTY_MAP);
> resource.save(Collections.EMPTY_MAP);
> }
> catch (Exception exception) {
> resourceToDiagnosticMap.put(resource,
> analyzeResourceProblems(resource, exception));
> }
> first = false;
> }
> }
>
>
> Is it normal ?
> Thanks for your help
>
> Marie
>
> Ed Merks a écrit :
>> Marie,
>>
>> If you has a String rather than a DOM to start with, this would
>> perform significantly better:
>>
>> resource.load(new InputSource(new StringReader(document.get())),
>> Collections.EMPTY_MAP);
>>
>>
>> Marie C wrote:
>>> Many thanks Ed !!
>>> It works for me.
>>>
>>> /**
>>> *
>>> */
>>> protected void handleStructuredModelChange() {
>>> try { // get resource
>>> XMLResource resource =
>>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>> // save it in DOM
>>> Document xmlDom = resource.save(null, Collections.EMPTY_MAP, null);
>>> // load it
>>> resource.load(xmlDom, Collections.EMPTY_MAP);
>>> } catch (Exception e) {}
>>> }
>>>
>>> /**
>>> *
>>> */
>>> protected void handleDocumentChange() {
>>> try {
>>> IDocument document =
>>> xmlEditor.getDocumentProvider().getDocument(xmlEditor.getEdi torInput());
>>>
>>>
>>> // get resource
>>> XMLResource xmlResource =
>>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>>
>>> // unload resource
>>> if (xmlResource.isLoaded()) {
>>> xmlResource.unload();
>>> }
>>>
>>> // construct new DOM
>>> DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
>>> DocumentBuilder builder = factory.newDocumentBuilder();
>>> Document newDom = builder.parse(new InputSource(new
>>> StringReader(document.get())));
>>>
>>> // load resource
>>> xmlResource.load(newDom, Collections.EMPTY_MAP);
>>> } catch (Exception e) {}
>>>
>>>
>>>
>>> Marie
>>>
>>>
>>>
>>>
>>> Ed Merks a écrit :
>>>> Marie,
>>>>
>>>> I suggested using this load method to load directly from the DOM
>>>> that is supported by SSE:
>>>>
>>>> /**
>>>> * Loads the resource from the DOM node, either an Element or
>>>> Document, using the specified options.
>>>> * <p>
>>>> * This method assumes that no namespace fixup needs to be done.
>>>> * To process comments and CDATA section nodes, please set
>>>> XMLResource.OPTION_USE_LEXICAL_HANDLER option to Boolean.TRUE.
>>>> * </p>
>>>> * @param node DOM Element or Document node.
>>>> * @param options the load options.
>>>> * @see #save(Document, Map, DOMHandler)
>>>> * @since 2.1.0
>>>> */
>>>> void load(Node node, Map<?, ?> options) throws IOException;
>>>>
>>>> You can look at the source code for the XSD model's sample
>>>> XSDEditor to see a very crude way in which we sync up the source
>>>> and the resource. You can see that whenever a command is executed
>>>> on the model, handleStructuredModelChange is called to update the
>>>> document with the new serialized version. You'd want to use to
>>>> serialize directly to the SSE DOM.
>>>>
>>>> /**
>>>> * Create a DOM tree representing contents of this resource.
>>>> * @param document an empty {@link org.w3c.dom.Document} to
>>>> use or
>>>> null. If no document is specified, the
>>>> * new {@link org.w3c.dom.Document} will be created using
>>>> JAXP API.
>>>> * @param options the "save" options
>>>> * @param handler the {@link
>>>> org.eclipse.emf.ecore.xmi.DOMHandler}
>>>> to record mappings or null.
>>>> * If no DOMHandler is passed, the default DOMHandler will be
>>>> created.
>>>> * @return the {@link org.w3c.dom.Document}. In the case the
>>>> document is specified as a parameter,
>>>> * the returned document is the same as the one specified,
>>>> otherwise the newly created document is returned.
>>>> * @since 2.1.0
>>>> */
>>>> Document save(Document document, Map<?, ?> options, DOMHandler
>>>> handler);
>>>>
>>>> In createSourcePage you'll see we hook up a listener to the
>>>> document so when it changes, handleDocumentChange is called to
>>>> update the document. In your case, you'd call the above load
>>>> method again.
>>>>
>>>>
>>>> Marie C wrote:
>>>>> Thanks a lot Ed for your answer.
>>>>>
>>>>> I understand your explanation.
>>>>>
>>>>> However, how modify the editing domain resource ?
>>>>>
>>>>> For example, with the following code, resource is never modified.
>>>>>
>>>>> // xmlSource is StructuredTextEditor
>>>>> IDocument doc =
>>>>> xmlSource.getDocumentProvider().getDocument(getEditorInput() );
>>>>> ....
>>>>> XMLResource initialResource =
>>>>> (XMLResource)editingDomain.getResourceSet().getResources().g et(0);
>>>>>
>>>>> initialResource.load(new
>>>>> ByteArrayInputStream(doc.get().getBytes()), null);
>>>>>
>>>>> // display the content of the resource in sysout
>>>>> initialResource.save(System.out, Collections.EMPTY_MAP);
>>>>>
>>>>>
>>>>>
>>>>> Thanks for your help
>>>>>
>>>>> Marie
>>>>>
>>>>> Ed Merks a écrit :
>>>>>> Marie,
>>>>>>
>>>>>> Comments below.
>>>>>>
>>>>>> Marie C wrote:
>>>>>>> Hi to all,
>>>>>>>
>>>>>>> First excuse my bad English ;-)
>>>>>> As long as you'll excuse my exclusive use of English.
>>>>>>>
>>>>>>> I'm using Eclipse 3.2 with EMF 2.2 and I'm developing an XML
>>>>>>> editor plugin.
>>>>>>>
>>>>>>> From XSD schema, I have generated the Ecore model and from
>>>>>>> genmodel the model code, edit code and editor code.
>>>>>>>
>>>>>>> The createPages() method of editor class creates a page for the
>>>>>>> EMF tree viewer (named viewerPane).
>>>>>>>
>>>>>>> I've added to the editor a StructuredTextEditor by adding this
>>>>>>> snippet code in createPages() method of editor class:
>>>>>>>
>>>>>>> try { StructuredTextEditor xmlSource = new
>>>>>>> StructuredTextEditor(); int index = addPage(xmlSource,
>>>>>>> getEditorInput());
>>>>>>> setPageText(index, xmlSource.getTitle());
>>>>>>> } catch (PartInitException pie) {}
>>>>>>>
>>>>>>> I would like the XML Source to be synchronized with the EMF
>>>>>>> tree. Actually when a modification occurs on EMF tree, XML view
>>>>>>> is also updated with this modification ... but on the contrary a
>>>>>>> modification on XML source doesn't occur on EMF tree.
>>>>>>>
>>>>>>> Is there a simple way for implement this?
>>>>>>>
>>>>>>> I've heard about SSE, EMF2DOM adapters ... but I've not found
>>>>>>> any sample or snippet code for doing that.
>>>>>> It's a pretty tricky problem that I wish we had a good reusable
>>>>>> solution for already. All I can suggest that would be fairly
>>>>>> easy would be kind of brute force solutions. Using
>>>>>> XMLResource.save(Document document, Map<?, ?> options, DOMHandler
>>>>>> handler) with a handler you could convert a model to a SSE DOM
>>>>>> maintaining a mapping from the EObject to the DOM. When the
>>>>>> model changes, you could repeat that process. If the DOM
>>>>>> changes, you could unload the EMF resource and use void
>>>>>> load(Node node, Map<?, ?> options). It's very crude but that's
>>>>>> the best I can suggest. I imagine one could do some very nice
>>>>>> fine grained integration to support an EMF2DOM adapter
>>>>>> automatically given the extended metadata annotations on the
>>>>>> model, but I can't point you at any source code for that. It
>>>>>> would make a great EMFT component...
>>>>>>>
>>>>>>> Thanks a lot for your help
>>>>>>>
>>>>>>> Marie
>>>>
>>
Re: XML (Structured) Text editor synchronized with EMF view [message #968703 is a reply to message #414485] Fri, 02 November 2012 13:30 Go to previous messageGo to next message
Rob Cernich is currently offline Rob Cernich
Messages: 40
Registered: September 2011
Member
Sorry to hijack this thread, but...

> It's a pretty tricky problem that I wish we had a good reusable
> solution for already. All I can suggest that would be fairly
> easy would be kind of brute force solutions. Using
> XMLResource.save(Document document, Map<?, ?> options, DOMHandler
> handler) with a handler you could convert a model to a SSE DOM
> maintaining a mapping from the EObject to the DOM. When the
> model changes, you could repeat that process. If the DOM
> changes, you could unload the EMF resource and use void
> load(Node node, Map<?, ?> options). It's very crude but that's
> the best I can suggest. I imagine one could do some very nice
> fine grained integration to support an EMF2DOM adapter
> automatically given the extended metadata annotations on the
> model, but I can't point you at any source code for that. It
> would make a great EMFT component...

I've been working on just such a thing. A few classes, a little ExtendedMetaData magic and a generic solution that bridges the gap between EMF and SSE. Is such a thing still needed? Is EMF2DOM still the way to go when it comes to adding source pages to editors working on EMF models?

It's still a work in progress and needs to be cleaned up, but the beginnings can be found here: https://github.com/rcernich/tools/tree/text_editing/eclipse/plugins/org.switchyard.tools.ui.editor/src/org/switchyard/tools/ui/editor/dom

Best,
Rob
Re: XML (Structured) Text editor synchronized with EMF view [message #969348 is a reply to message #968703] Sat, 03 November 2012 02:03 Go to previous message
Ed Merks is currently offline Ed Merks
Messages: 25943
Registered: July 2009
Senior Member
Rob,

Certainly if anyone wishes to have a source view of their serialized
model, I can't think of a better approach than using SSE, with its
specialized XML support, as the basis for such a source view. Could you
please open an EMF bugzilla enhancement request with links and an
explicit statement of your intent to donate the code under EPL and a
statement about the origin of the code, i.e., who hold the copyrights to
all the code. Of course including license and copyright information in
each source file (as we do for all Eclipse source) is the best way to
track that...


On 02/11/2012 6:30 PM, Rob Cernich wrote:
> Sorry to hijack this thread, but...
>
>> It's a pretty tricky problem that I wish we had a good reusable
>> solution for already. All I can suggest that would be fairly
>> easy would be kind of brute force solutions. Using
>> XMLResource.save(Document document, Map<?, ?> options, DOMHandler
>> handler) with a handler you could convert a model to a SSE DOM
>> maintaining a mapping from the EObject to the DOM. When the
>> model changes, you could repeat that process. If the DOM
>> changes, you could unload the EMF resource and use void
>> load(Node node, Map<?, ?> options). It's very crude but that's
>> the best I can suggest. I imagine one could do some very nice
>> fine grained integration to support an EMF2DOM adapter
>> automatically given the extended metadata annotations on the
>> model, but I can't point you at any source code for that. It
>> would make a great EMFT component...
>
> I've been working on just such a thing. A few classes, a little
> ExtendedMetaData magic and a generic solution that bridges the gap
> between EMF and SSE. Is such a thing still needed? Is EMF2DOM still
> the way to go when it comes to adding source pages to editors working
> on EMF models?
>
> It's still a work in progress and needs to be cleaned up, but the
> beginnings can be found here:
> https://github.com/rcernich/tools/tree/text_editing/eclipse/plugins/org.switchyard.tools.ui.editor/src/org/switchyard/tools/ui/editor/dom
>
> Best,
> Rob
Previous Topic:EMF resource how to flush to disk
Next Topic:EcoreUtil.equals fails for EObjects read from 2 XML files which are actually copies of each other
Goto Forum:
  


Current Time: Wed Jul 30 07:22:33 EDT 2014

Powered by FUDForum. Page generated in 0.05493 seconds