Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Re: Add New Resource Storage Mechanism
Re: Add New Resource Storage Mechanism [message #419542] Mon, 26 May 2008 20:50 Go to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Martin,

Please use the EMF newsgroup for EMF questions in the future. I've
added it to the "to" list of the reply.


Martin Geisse wrote:
> Hello,
>
> I am currently writing a plug-in that adds a new mechanism for ecore
> resource storage. Basically, I want to have EMF recognize a distinct
> kind of URIs and redirect them to my plug-in. I do not require special
> behaviour of the Resource instances, only custom input/output streams.
> In fact, I want to re-use the behaviour of existing resource
> implementations (and corresponding resource factories) such that they
> impose "their" file format on the input/output streams that I provide.
>
> To me it seems that the proper solution is a custom implementation of
> either URIConverter or URIHandler.
Yes, a URIHandler should suffice.
>
> However, I want the new kind of URI to be available for any entity
> that resolves resources using URIs, without specific knowledge about
> my plug-in.
Hmmm. I didn't make the handlers a pluggable thing because each handler
adds a bit of overhead and I was concerned that not all clients will
want such handlers injected into their environment...
> For instance, I want the example editors which are generated from
> ecore models to be able to load resources using "my" URIs and point
> ERereference variables to objects contained in them. This indicates
> that my custom URI handling code must be registered globally in some
> way, but I am unsure where the best place is for this.
I suppose you could also take the approach of defining an actual URL
handler. You could look at org.eclipse.emf.common.archive.Handler as an
example of how you could register a URL handler that would work
universally throughout the JRE.
>
> I have found URIConverter.INSTANCE, but the documentation says that
> "It's generally not a good idea to modify any aspect of this
> instance", which rules it out for my purpose because adding a custom
> URI handler to it is clearly modifying the instance.
And besides, resource set's have local URI converter and only the
handlers on that instance are used within the resource set.
>
> I have found URIHandler.DEFAULT_HANDLER, but again the documentation
> says that it is read-only.
Yes, I'm concerned that 100 different plugins might inject behavior for
all applications, that they might compete for priority (being ahead on
the list) and might usurp control...
>
> I have found the "org.eclipse.emf.ecore.protocol_parser" extension
> point, but this allows me to register a resource factory, not an URI
> handler / converter, which is not what I want. Specifically, by using
> a custom resource factory I would bypass the existing resource
> factories that implement specific file formats for the various models,
> when in reality I want to use those existing factories, only with
> custom code for creating the raw data streams.
Another approach would be to make use of the Eclipse File System, EFS.
An interesting aspect of that is you could even use this to surface your
scheme as real IFiles in the workspace. The existing URI handlers
include ones that will delegate to EFS for any scheme supported by EFS.
A bit of googling should find you some nice documentation about this.
We're able to open resources in a CVS repository because of EFS support
for that...
>
> Can anyone point me to the right direction?
> Thanks in advance,
> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419544 is a reply to message #419542] Mon, 26 May 2008 22:55 Go to previous messageGo to next message
Martin Geisse is currently offline Martin GeisseFriend
Messages: 24
Registered: July 2009
Junior Member
Ed Merks wrote:

> Martin,
>
> Please use the EMF newsgroup for EMF questions in the future. I've
> added it to the "to" list of the reply.

Thank you.

> Hmmm. I didn't make the handlers a pluggable thing because each handler
> adds a bit of overhead and I was concerned that not all clients will
> want such handlers injected into their environment...

Not having the handlers (or any equivalent mechanism) in place
everywhere would mean that the new kind of URI would - in a seemingly
random way to the end-user - work or not work. I understand the
performance considerations, but then I'd rather allow my plug-in to be
turned off altogether for performance-critical applications.

> I suppose you could also take the approach of defining an actual URL
> handler. You could look at org.eclipse.emf.common.archive.Handler as an
> example of how you could register a URL handler that would work
> universally throughout the JRE.

Defining an URL handler looks promising to me. However, the example you
have given confuses me: First, the registration method that tells Java
where the URLStreamHandler can be found is called only from main, which
is not called from any other code. That is fine for a standalone
application, but I wonder where the registration is invoked when the
whole thing is run as an Eclipse plug-in. Secondly, I tried registering
my own handler at Eclipse start-up, but Java always fails to load the
URLStreamHandler class (I suspect this to be caused by the way Eclipse
loads classes contained in plug-ins).

> And besides, resource set's have local URI converter and only the
> handlers on that instance are used within the resource set.

Thanks for the information. I was under the impression that the local
URI converters delegate unrecognized URIs to the global one.

> Yes, I'm concerned that 100 different plugins might inject behavior for
> all applications, that they might compete for priority (being ahead on
> the list) and might usurp control...

Understood.

> Another approach would be to make use of the Eclipse File System, EFS.
> An interesting aspect of that is you could even use this to surface your
> scheme as real IFiles in the workspace.

Unfortunately, the storage mechanism I have in mind has little in common
with files. Hiding it behind URLs or URIs should work, but not so for IFile.

Greetings,
Martin Geisse
Re: Add New Resource Storage Mechanism [message #419545 is a reply to message #419544] Mon, 26 May 2008 23:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Martin,

Comments below.


Martin Geisse wrote:
> Ed Merks wrote:
>
>> Martin,
>>
>> Please use the EMF newsgroup for EMF questions in the future. I've
>> added it to the "to" list of the reply.
>
> Thank you.
>
>> Hmmm. I didn't make the handlers a pluggable thing because each
>> handler adds a bit of overhead and I was concerned that not all
>> clients will want such handlers injected into their environment...
>
> Not having the handlers (or any equivalent mechanism) in place
> everywhere would mean that the new kind of URI would - in a seemingly
> random way to the end-user - work or not work. I understand the
> performance considerations, but then I'd rather allow my plug-in to be
> turned off altogether for performance-critical applications.
The questions remains. How would your new kind of URI even show up?
Normally when the user opens up a resource in the workspace, it will be
platform:/resource/<project>/<path>/<file>. So how do you imagine your
specialized URI would show up elsewhere? And in the end, it's not so
much would you would like to see but rather what would the other 100 EMF
clients expect for their applications...
>
>> I suppose you could also take the approach of defining an actual URL
>> handler. You could look at org.eclipse.emf.common.archive.Handler as
>> an example of how you could register a URL handler that would work
>> universally throughout the JRE.
>
> Defining an URL handler looks promising to me. However, the example
> you have given confuses me: First, the registration method that tells
> Java where the URLStreamHandler can be found is called only from main,
> which is not called from any other code.
You'd need to ensure it gets called during starting, so you might invoke
this during an eager starting plugin...
> That is fine for a standalone application, but I wonder where the
> registration is invoked when the whole thing is run as an Eclipse
> plug-in.
You can make your plugin eager, but that's generally frowned upon.
> Secondly, I tried registering my own handler at Eclipse start-up, but
> Java always fails to load the URLStreamHandler class (I suspect this
> to be caused by the way Eclipse loads classes contained in plug-ins).
You'll need to be more specific. A plugin shouldn't need to do anything
fancy for its classes to be loaded...
>
>> And besides, resource set's have local URI converter and only the
>> handlers on that instance are used within the resource set.
>
> Thanks for the information. I was under the impression that the local
> URI converters delegate unrecognized URIs to the global one.
Not in terms of the handers, no.
>
>> Yes, I'm concerned that 100 different plugins might inject behavior
>> for all applications, that they might compete for priority (being
>> ahead on the list) and might usurp control...
>
> Understood.
>
>> Another approach would be to make use of the Eclipse File System,
>> EFS. An interesting aspect of that is you could even use this to
>> surface your scheme as real IFiles in the workspace.
>
> Unfortunately, the storage mechanism I have in mind has little in
> common with files. Hiding it behind URLs or URIs should work, but not
> so for IFile.
I doubt that's true. EFS relies on the same type of thing as to URL
connections. I.e., the ability to create input and output streams. In
both cases, all that's needed is some way of storing or retrieving the
bytes...
>
> Greetings,
> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419547 is a reply to message #419545] Tue, 27 May 2008 00:36 Go to previous messageGo to next message
Martin Geisse is currently offline Martin GeisseFriend
Messages: 24
Registered: July 2009
Junior Member
> The questions remains. How would your new kind of URI even show up?
> Normally when the user opens up a resource in the workspace, it will be
> platform:/resource/<project>/<path>/<file>. So how do you imagine your
> specialized URI would show up elsewhere? And in the end, it's not so
> much would you would like to see but rather what would the other 100 EMF
> clients expect for their applications...

As far as I understand, the target of an EReference is specified by an
URI, and is not restricted to resources in the workspace. At least that
is what I concluded from URI instances being passed around all over the
ecore code instead of Eclipse's IPath or similar.

The way these URIs are used is pretty obvious to me. A user opens some
model in its editor, selects "Load Resource" as if any other resource is
loaded, and enters the specialized URI instead of a platform:/resource
one. The URI is used to create input/output streams, and the rest works
normally.

As far as other users are concerned, they would not even realize the
existence of my work unless they (consciously) choose to type in one of
those custom URIs.

> You'd need to ensure it gets called during starting, so you might invoke
> this during an eager starting plugin...
[...]
> You can make your plugin eager, but that's generally frowned upon.
[...]
> You'll need to be more specific. A plugin shouldn't need to do anything
> fancy for its classes to be loaded...

I have made the plugin eager for testing purposes. This allows my code
to run at startup. At that time, I try to registry my custom URL handler
(by setting the corresponding system property, which works), but
subsequent creation an URL using "my" protocol fails, claiming that the
URLStreamHandler class could not be loaded, despite the fact that it has
already been loaded (i have put the registration code into the same
class, so I'm sure the class has been loaded).

Short version: Code from my class is already being executed, but the
java.net stuff still complains the class cannot be loaded.

I'd like to believe that, as you say, the classes from a plugin are
loaded without any fancy stuff, but I'm running out of simpler explanations.

>>> Another approach would be to make use of the Eclipse File System,
>>> EFS. An interesting aspect of that is you could even use this to
>>> surface your scheme as real IFiles in the workspace.
>>
>> Unfortunately, the storage mechanism I have in mind has little in
>> common with files. Hiding it behind URLs or URIs should work, but not
>> so for IFile.
> I doubt that's true. EFS relies on the same type of thing as to URL
> connections. I.e., the ability to create input and output streams. In
> both cases, all that's needed is some way of storing or retrieving the
> bytes...

Seems like I'll have to take a deeper look at EFS before I can comment
on this.

Greetings,
Martin Geisse
Re: Add New Resource Storage Mechanism [message #419548 is a reply to message #419547] Tue, 27 May 2008 01:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Martin,

Comments below.


Martin Geisse wrote:
>
>> The questions remains. How would your new kind of URI even show up?
>> Normally when the user opens up a resource in the workspace, it will
>> be platform:/resource/<project>/<path>/<file>. So how do you imagine
>> your specialized URI would show up elsewhere? And in the end, it's
>> not so much would you would like to see but rather what would the
>> other 100 EMF clients expect for their applications...
>
> As far as I understand, the target of an EReference is specified by an
> URI, and is not restricted to resources in the workspace. At least
> that is what I concluded from URI instances being passed around all
> over the ecore code instead of Eclipse's IPath or similar.
Definitely a resource can use any URI. But of course in general, an
IFile is being opened and in that case the URI used for the initial
resource is platform:/resource/...
>
> The way these URIs are used is pretty obvious to me. A user opens some
> model in its editor, selects "Load Resource" as if any other resource
> is loaded, and enters the specialized URI instead of a
> platform:/resource one. The URI is used to create input/output
> streams, and the rest works normally.
Yes, that's right. Using Load Resource you can enter pretty much anything.
>
> As far as other users are concerned, they would not even realize the
> existence of my work unless they (consciously) choose to type in one
> of those custom URIs.
Yep. The same is true of URLs in general. They just work.
>
>> You'd need to ensure it gets called during starting, so you might
>> invoke this during an eager starting plugin...
> [...]
>> You can make your plugin eager, but that's generally frowned upon.
> [...]
> > You'll need to be more specific. A plugin shouldn't need to do
> anything
> > fancy for its classes to be loaded...
>
> I have made the plugin eager for testing purposes. This allows my code
> to run at startup. At that time, I try to registry my custom URL
> handler (by setting the corresponding system property, which works),
> but subsequent creation an URL using "my" protocol fails, claiming
> that the URLStreamHandler class could not be loaded, despite the fact
> that it has already been loaded (i have put the registration code into
> the same class, so I'm sure the class has been loaded).
Hmmm. You might have to literally put your class on the JVM's
classpath. I've not played with t his.
>
> Short version: Code from my class is already being executed, but the
> java.net stuff still complains the class cannot be loaded.
>
> I'd like to believe that, as you say, the classes from a plugin are
> loaded without any fancy stuff, but I'm running out of simpler
> explanations.
Well, my point was more that the plugin just sees the classes, but if
there's other code involved that does Class.forName, the class loader
scoping becomes an issue.

Note that the platform scheme is registered as a real URL handler.
I.e., URLs that use platform: can use URL.openStream, so the platform
must have somehow solved this issue. I'm not sure how though...
>
>>>> Another approach would be to make use of the Eclipse File System,
>>>> EFS. An interesting aspect of that is you could even use this to
>>>> surface your scheme as real IFiles in the workspace.
>>>
>>> Unfortunately, the storage mechanism I have in mind has little in
>>> common with files. Hiding it behind URLs or URIs should work, but
>>> not so for IFile.
>> I doubt that's true. EFS relies on the same type of thing as to URL
>> connections. I.e., the ability to create input and output streams.
>> In both cases, all that's needed is some way of storing or retrieving
>> the bytes...
>
> Seems like I'll have to take a deeper look at EFS before I can comment
> on this.
I'm not really sure what your design goal is, but being able to surface
the files as IFiles in the workspace might be quite convenient...
>
> Greetings,
> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419564 is a reply to message #419548] Tue, 27 May 2008 15:50 Go to previous messageGo to next message
Martin Geisse is currently offline Martin GeisseFriend
Messages: 24
Registered: July 2009
Junior Member
Ed Merks wrote:

>>> I doubt that's true. EFS relies on the same type of thing as to URL
>>> connections. I.e., the ability to create input and output streams.
>>> In both cases, all that's needed is some way of storing or retrieving
>>> the bytes...
>>
>> Seems like I'll have to take a deeper look at EFS before I can comment
>> on this.
> I'm not really sure what your design goal is, but being able to surface
> the files as IFiles in the workspace might be quite convenient...

I understand what you mean, but I have taken a peek at EFS, and it
expects a lot more than just being able to create input/output streams
for each stored entity. What I have in mind has too little in common
with EFS files to disguise as an EFS extension.

Let's just start with the fact that EFS expects a file system
implementation to be able to return all subnodes of a FileStore in an
array, whereas for me at each point in time a node may have infinitely
many subnodes...

> Note that the platform scheme is registered as a real URL handler.
> I.e., URLs that use platform: can use URL.openStream, so the platform
> must have somehow solved this issue. I'm not sure how though...

I have found how to add a custom URL handler to java.net from within
Eclipse now (it must be registered as a service in OSGI). Things seem to
work now.

Thanks a lot for your help.

Greetings,
Martin Geisse
Re: Add New Resource Storage Mechanism [message #419565 is a reply to message #419564] Tue, 27 May 2008 16:10 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Martin,

Comments below.

Martin Geisse wrote:
> Ed Merks wrote:
>
> >>> I doubt that's true. EFS relies on the same type of thing as to URL
> >>> connections. I.e., the ability to create input and output streams.
> >>> In both cases, all that's needed is some way of storing or retrieving
> >>> the bytes...
> >>
> >> Seems like I'll have to take a deeper look at EFS before I can comment
> >> on this.
> > I'm not really sure what your design goal is, but being able to surface
> > the files as IFiles in the workspace might be quite convenient...
>
> I understand what you mean, but I have taken a peek at EFS, and it
> expects a lot more than just being able to create input/output streams
> for each stored entity. What I have in mind has too little in common
> with EFS files to disguise as an EFS extension.
It wants enough to be able to back and IResource which is more than what
EMF would need (though I don't think it's much more).
>
> Let's just start with the fact that EFS expects a file system
> implementation to be able to return all subnodes of a FileStore in an
> array, whereas for me at each point in time a node may have infinitely
> many subnodes...
That's quite a few! :-P
>
>> Note that the platform scheme is registered as a real URL handler.
>> I.e., URLs that use platform: can use URL.openStream, so the platform
>> must have somehow solved this issue. I'm not sure how though...
>
> I have found how to add a custom URL handler to java.net from within
> Eclipse now (it must be registered as a service in OSGI). Things seem
> to work now.
Excellent! I'd really appreciate if you described how to do that so
I'll know the next time someone asks.
>
> Thanks a lot for your help.
>
> Greetings,
> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419570 is a reply to message #419565] Tue, 27 May 2008 17:32 Go to previous messageGo to next message
Martin Geisse is currently offline Martin GeisseFriend
Messages: 24
Registered: July 2009
Junior Member
> Excellent! I'd really appreciate if you described how to do that so
> I'll know the next time someone asks.

Here you are:

In the Eclipse plug-in class (typically a nested class of the EMFPlugin
subclass) for the project, the start(BundleContext) method registers an
"URL stream handler service" with OSGI:

public void start (BundleContext context) throws Exception
{
Hashtable<Object,Object> properties =
new Hashtable<Object,Object> (1);
properties.put (
URLConstants.URL_HANDLER_PROTOCOL,
new String[] {"myprotocol"});
String serviceClass = URLStreamHandlerService.class.getName();
context.registerService (serviceClass,
new MyURLStreamHandlerService (),
properties);
}

URLConstants and URLStreamHandlerService are OSGI classes.
MyURLStreamHandlerService is my handler class, which is a subclass of
AbstractURLStreamHandlerService (another OSGI class). The above example
installs that handler for "myprotocol:" URLs.

A problem that I encountered is that the plug-in must be loaded on
startup (performance, I know...) because creating an URL instance
through java.net would not trigger the plug-in loading mechanism. This
is unfortunate, but I'll try hard to keep the overhead of just loading
the plugin to a minimum.

The automatic loading is done by an extension in the plug-in:

<plugin>
<extension point="org.eclipse.ui.startup">
<startup class="modelflow.StartupClass"/>
</extension>
</plugin>

and the corresponding class ("modelflow" is the name of the plugin):

public class StartupClass implements IStartup
{
public void earlyStartup ()
{
final IWorkbench workbench = PlatformUI.getWorkbench ();
workbench.getDisplay ().asyncExec (new Runnable () {
public void run () {
try {
Platform.getBundle ("modelflow").start ();
} catch (BundleException e) {
}
}
});
}
}

Greetings,
Martin Geisse
Re: Add New Resource Storage Mechanism [message #419572 is a reply to message #419570] Tue, 27 May 2008 17:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Martin,

Cool. Thanks for sharing that!


Martin Geisse wrote:
>> Excellent! I'd really appreciate if you described how to do that so
>> I'll know the next time someone asks.
>
> Here you are:
>
> In the Eclipse plug-in class (typically a nested class of the
> EMFPlugin subclass) for the project, the start(BundleContext) method
> registers an "URL stream handler service" with OSGI:
>
> public void start (BundleContext context) throws Exception
> {
> Hashtable<Object,Object> properties =
> new Hashtable<Object,Object> (1);
> properties.put (
> URLConstants.URL_HANDLER_PROTOCOL,
> new String[] {"myprotocol"});
> String serviceClass = URLStreamHandlerService.class.getName();
> context.registerService (serviceClass,
> new MyURLStreamHandlerService (),
> properties);
> }
>
> URLConstants and URLStreamHandlerService are OSGI classes.
> MyURLStreamHandlerService is my handler class, which is a subclass of
> AbstractURLStreamHandlerService (another OSGI class). The above
> example installs that handler for "myprotocol:" URLs.
>
> A problem that I encountered is that the plug-in must be loaded on
> startup (performance, I know...) because creating an URL instance
> through java.net would not trigger the plug-in loading mechanism. This
> is unfortunate, but I'll try hard to keep the overhead of just loading
> the plugin to a minimum.
>
> The automatic loading is done by an extension in the plug-in:
>
> <plugin>
> <extension point="org.eclipse.ui.startup">
> <startup class="modelflow.StartupClass"/>
> </extension>
> </plugin>
>
> and the corresponding class ("modelflow" is the name of the plugin):
>
> public class StartupClass implements IStartup
> {
> public void earlyStartup ()
> {
> final IWorkbench workbench = PlatformUI.getWorkbench ();
> workbench.getDisplay ().asyncExec (new Runnable () {
> public void run () {
> try {
> Platform.getBundle ("modelflow").start ();
> } catch (BundleException e) {
> }
> }
> });
> }
> }
>
> Greetings,
> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419639 is a reply to message #419572] Fri, 30 May 2008 09:14 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: laurent.legoff.geensy.com

Hi,
I read quickly the thread and I would like to share my experience of
creating a filesystem with EFS. I hope it will interest you.

I created a filesystem to be able to view plugin resources
(platform:/plugin/my_plugin/my_resource.xmi) as IFile

You can now doing such a thing:
IContainer container; // a folder
container.getFile("my_resource.xmi");
container.createLink(new
URI("platform:/plugin/my_plugin/my_resource.xmi"),
IResource.ALLOW_MISSING_LOCAL,new NullProgressMonitor());

if you use now this filesystem in conjunction with EMF resource mecanism
you can load this IFile as a normal IFile.

Be Careful if you use the default emf editor that use the method
isReadOnly() of AdapterFactoryEditingDomain: this throw a
NullPointerExption (see call of method: URI localURI =
CommonPlugin.asLocalURI(uri); that cannot convert to a local URI and
throw an NullPointerExption).

To avoid this problem I use the URIConverter of the ResourceSet, now
when URIConverter normalize the URI it return the linked resource, so
platform:/plugin/my_plugin/my_resource.xmi
if (file.getLocation() == null && file.getLocationURI() != null) {
// this is not a local file system it's under another...
URI link =
URI.createPlatformResourceURI(file.getFullPath().toString(), true);
URI target = URI.createURI(file.getLocationURI().toString());
resourceSet.getURIConverter().getURIMap().put(link, target);
}



This filesystem is very simple to create just view the
PlatformPluginFileStore class (note that I use URL defined by a special
URLHandler for plugin by OSGI: uri.toURL()):

// here the file is always readonly and never a folder
public class PlatformPluginFileStore extends FileStore {

protected URI uri;

public PlatformPluginFileStore(URI uri) {
this.uri = uri;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#fetchInfo(int ,
org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo fetchInfo(int options, IProgressMonitor monitor)
throws CoreException {
// in-lined non-native implementation
FileInfo info = new FileInfo(getName());
info.setExists(true);
info.setDirectory(false);
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, true);
info.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
return info;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#childNames(in t,
org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public String[] childNames(int options, IProgressMonitor monitor)
throws CoreException {
return new String[] {};
}

/*
* @see
org.eclipse.core.filesystem.provider.FileStore#getChild(java .lang.String)
*/
@Override
public IFileStore getChild(String name) {
return null;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#getName()
*/
@Override
public String getName() {
String path = uri.getPath();
int lastIndexOf = path.lastIndexOf('/');
if (lastIndexOf >= 0 && lastIndexOf < path.length() - 1) {
return path.substring(lastIndexOf + 1, path.length());
}
return path;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#getParent()
*/
@Override
public IFileStore getParent() {
return null;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#openInputStre am(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public InputStream openInputStream(int options, IProgressMonitor
monitor) throws CoreException {
try {
return uri.toURL().openStream();
} catch (MalformedURLException ex) {
throw new CoreException(new Status(IStatus.ERROR,
Activator.getDefault().getBundle().getSymbolicName(), "Error opening
strean on file",
ex));
} catch (IOException ex) {
throw new CoreException(new Status(IStatus.ERROR,
Activator.getDefault().getBundle().getSymbolicName(), "Error opening
strean on file",
ex));
}
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#toURI()
*/
@Override
public URI toURI() {
return uri;
}

}

Imagine now you create filesystem that return an InputStream for this
URI: library:/book/author .... :-)

best regards,
HTH
Laurent Le Goff

Ed Merks a écrit :
> Martin,
>
> Cool. Thanks for sharing that!
>
>
> Martin Geisse wrote:
>>> Excellent! I'd really appreciate if you described how to do that so
>>> I'll know the next time someone asks.
>>
>> Here you are:
>>
>> In the Eclipse plug-in class (typically a nested class of the
>> EMFPlugin subclass) for the project, the start(BundleContext) method
>> registers an "URL stream handler service" with OSGI:
>>
>> public void start (BundleContext context) throws Exception
>> {
>> Hashtable<Object,Object> properties =
>> new Hashtable<Object,Object> (1);
>> properties.put (
>> URLConstants.URL_HANDLER_PROTOCOL,
>> new String[] {"myprotocol"});
>> String serviceClass = URLStreamHandlerService.class.getName();
>> context.registerService (serviceClass,
>> new MyURLStreamHandlerService (),
>> properties);
>> }
>>
>> URLConstants and URLStreamHandlerService are OSGI classes.
>> MyURLStreamHandlerService is my handler class, which is a subclass of
>> AbstractURLStreamHandlerService (another OSGI class). The above
>> example installs that handler for "myprotocol:" URLs.
>>
>> A problem that I encountered is that the plug-in must be loaded on
>> startup (performance, I know...) because creating an URL instance
>> through java.net would not trigger the plug-in loading mechanism. This
>> is unfortunate, but I'll try hard to keep the overhead of just loading
>> the plugin to a minimum.
>>
>> The automatic loading is done by an extension in the plug-in:
>>
>> <plugin>
>> <extension point="org.eclipse.ui.startup">
>> <startup class="modelflow.StartupClass"/>
>> </extension>
>> </plugin>
>>
>> and the corresponding class ("modelflow" is the name of the plugin):
>>
>> public class StartupClass implements IStartup
>> {
>> public void earlyStartup ()
>> {
>> final IWorkbench workbench = PlatformUI.getWorkbench ();
>> workbench.getDisplay ().asyncExec (new Runnable () {
>> public void run () {
>> try {
>> Platform.getBundle ("modelflow").start ();
>> } catch (BundleException e) {
>> }
>> }
>> });
>> }
>> }
>>
>> Greetings,
>> Martin Geisse
Re: Add New Resource Storage Mechanism [message #419640 is a reply to message #419639] Fri, 30 May 2008 10:47 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Laurent,

Comments below.


Laurent Le Goff wrote:
> Hi,
> I read quickly the thread and I would like to share my experience of
> creating a filesystem with EFS. I hope it will interest you.
>
> I created a filesystem to be able to view plugin resources
> (platform:/plugin/my_plugin/my_resource.xmi) as IFile
Hey, that sounds cool.
>
> You can now doing such a thing:
> IContainer container; // a folder
> container.getFile("my_resource.xmi");
> container.createLink(new
> URI("platform:/plugin/my_plugin/my_resource.xmi"),
> IResource.ALLOW_MISSING_LOCAL,new NullProgressMonitor());
I see, create link to your EFS URI which points at a file in a plugin.
>
> if you use now this filesystem in conjunction with EMF resource
> mecanism you can load this IFile as a normal IFile.
>
> Be Careful if you use the default emf editor that use the method
> isReadOnly() of AdapterFactoryEditingDomain: this throw a
> NullPointerExption (see call of method: URI localURI =
> CommonPlugin.asLocalURI(uri); that cannot convert to a local URI and
> throw an NullPointerExption).
It seems someone else had such an issue; maybe it was in this thread.
Could you show the stack trace? Probably a bugzilla should be opened
for the problem...
>
> To avoid this problem I use the URIConverter of the ResourceSet, now
> when URIConverter normalize the URI it return the linked resource, so
> platform:/plugin/my_plugin/my_resource.xmi
> if (file.getLocation() == null && file.getLocationURI() != null) {
> // this is not a local file system it's under
> another...
> URI link =
> URI.createPlatformResourceURI(file.getFullPath().toString(), true);
> URI target =
> URI.createURI(file.getLocationURI().toString());
>
> resourceSet.getURIConverter().getURIMap().put(link, target);
> }
This is to avoid the null pointer thing?

The isReadOnly thing has come up several times and it seems to me this
is an issue that needs to be revisited. The URI converter now supports
ATTRIBUTE_READ_ONLY so that would be a better way to check. We should
revisit this in 2.5. Perhaps you could open a bugzilla for this.
>
>
>
> This filesystem is very simple to create just view the
> PlatformPluginFileStore class (note that I use URL defined by a
> special URLHandler for plugin by OSGI: uri.toURL()):
>
> // here the file is always readonly and never a folder
> public class PlatformPluginFileStore extends FileStore {
>
> protected URI uri;
Is it an EMF URI or a java.net.URI?
>
> public PlatformPluginFileStore(URI uri) {
> this.uri = uri;
> }
>
> /*
> * @see
> org.eclipse.core.filesystem.provider.FileStore#fetchInfo(int ,
> org.eclipse.core.runtime.IProgressMonitor)
> */
> @Override
> public IFileInfo fetchInfo(int options, IProgressMonitor monitor)
> throws CoreException {
> // in-lined non-native implementation
> FileInfo info = new FileInfo(getName());
> info.setExists(true);
> info.setDirectory(false);
> info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, true);
> info.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
> return info;
> }
>
> /*
> * @see
> org.eclipse.core.filesystem.provider.FileStore#childNames(in t,
> org.eclipse.core.runtime.IProgressMonitor)
> */
> @Override
> public String[] childNames(int options, IProgressMonitor monitor)
> throws CoreException {
> return new String[] {};
Could use a constant....
> }
>
> /*
> * @see
> org.eclipse.core.filesystem.provider.FileStore#getChild(java .lang.String)
> */
> @Override
> public IFileStore getChild(String name) {
> return null;
> }
>
> /*
> * @see org.eclipse.core.filesystem.provider.FileStore#getName()
> */
> @Override
> public String getName() {
> String path = uri.getPath();
> int lastIndexOf = path.lastIndexOf('/');
> if (lastIndexOf >= 0 && lastIndexOf < path.length() - 1) {
> return path.substring(lastIndexOf + 1, path.length());
> }
> return path;
> }
>
> /*
> * @see org.eclipse.core.filesystem.provider.FileStore#getParent()
> */
> @Override
> public IFileStore getParent() {
> return null;
> }
>
> /*
> * @see
> org.eclipse.core.filesystem.provider.FileStore#openInputStre am(int,
> * org.eclipse.core.runtime.IProgressMonitor)
> */
> @Override
> public InputStream openInputStream(int options, IProgressMonitor
> monitor) throws CoreException {
> try {
> return uri.toURL().openStream();
> } catch (MalformedURLException ex) {
> throw new CoreException(new Status(IStatus.ERROR,
> Activator.getDefault().getBundle().getSymbolicName(), "Error opening
> strean on file",
> ex));
A Malformed URI Exception is an IOException, so you could eliminate this
clause.
> } catch (IOException ex) {
> throw new CoreException(new Status(IStatus.ERROR,
> Activator.getDefault().getBundle().getSymbolicName(), "Error opening
> strean on file",
> ex));
> }
> }
>
> /*
> * @see org.eclipse.core.filesystem.provider.FileStore#toURI()
> */
> @Override
> public URI toURI() {
> return uri;
> }
>
> }
>
> Imagine now you create filesystem that return an InputStream for this
> URI: library:/book/author .... :-)
That's so simple! I could imagine making an EFS for a jar which easily...

Probably it would be good to open bugzillas about the null pointer
exception and about better isReadOnly support...
>
> best regards,
> HTH
> Laurent Le Goff
>
> Ed Merks a écrit :
>> Martin,
>>
>> Cool. Thanks for sharing that!
>>
>>
>> Martin Geisse wrote:
>>>> Excellent! I'd really appreciate if you described how to do that
>>>> so I'll know the next time someone asks.
>>>
>>> Here you are:
>>>
>>> In the Eclipse plug-in class (typically a nested class of the
>>> EMFPlugin subclass) for the project, the start(BundleContext) method
>>> registers an "URL stream handler service" with OSGI:
>>>
>>> public void start (BundleContext context) throws Exception
>>> {
>>> Hashtable<Object,Object> properties =
>>> new Hashtable<Object,Object> (1);
>>> properties.put (
>>> URLConstants.URL_HANDLER_PROTOCOL,
>>> new String[] {"myprotocol"});
>>> String serviceClass = URLStreamHandlerService.class.getName();
>>> context.registerService (serviceClass,
>>> new MyURLStreamHandlerService (),
>>> properties);
>>> }
>>>
>>> URLConstants and URLStreamHandlerService are OSGI classes.
>>> MyURLStreamHandlerService is my handler class, which is a subclass
>>> of AbstractURLStreamHandlerService (another OSGI class). The above
>>> example installs that handler for "myprotocol:" URLs.
>>>
>>> A problem that I encountered is that the plug-in must be loaded on
>>> startup (performance, I know...) because creating an URL instance
>>> through java.net would not trigger the plug-in loading mechanism.
>>> This is unfortunate, but I'll try hard to keep the overhead of just
>>> loading the plugin to a minimum.
>>>
>>> The automatic loading is done by an extension in the plug-in:
>>>
>>> <plugin>
>>> <extension point="org.eclipse.ui.startup">
>>> <startup class="modelflow.StartupClass"/>
>>> </extension>
>>> </plugin>
>>>
>>> and the corresponding class ("modelflow" is the name of the plugin):
>>>
>>> public class StartupClass implements IStartup
>>> {
>>> public void earlyStartup ()
>>> {
>>> final IWorkbench workbench = PlatformUI.getWorkbench ();
>>> workbench.getDisplay ().asyncExec (new Runnable () {
>>> public void run () {
>>> try {
>>> Platform.getBundle ("modelflow").start ();
>>> } catch (BundleException e) {
>>> }
>>> }
>>> });
>>> }
>>> }
>>>
>>> Greetings,
>>> Martin Geisse


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419650 is a reply to message #419639] Fri, 30 May 2008 22:53 Go to previous messageGo to next message
Al B is currently offline Al BFriend
Messages: 130
Registered: July 2009
Senior Member
Hi,

>I created a filesystem to be able to view plugin resources
(platform:/plugin/my_plugin/my_resource.xmi) as IFile

Since IMarkers are objects associated with IFiles, does it mean that if I
load my EMF resource via this mechanism, then emf.validation.markers will
be able to display the errors/warnings on the Problems when
MarkerUtil.createMarkers(status) is called? Even when the application does
not load the model as workspace resource?
Re: Add New Resource Storage Mechanism [message #419651 is a reply to message #419650] Fri, 30 May 2008 23:13 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
AJ,

I think so.


AJ wrote:
> Hi,
>
>> I created a filesystem to be able to view plugin resources
> (platform:/plugin/my_plugin/my_resource.xmi) as IFile
>
> Since IMarkers are objects associated with IFiles, does it mean that
> if I load my EMF resource via this mechanism, then
> emf.validation.markers will be able to display the errors/warnings on
> the Problems when MarkerUtil.createMarkers(status) is called? Even
> when the application does not load the model as workspace resource?
>
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Add New Resource Storage Mechanism [message #419676 is a reply to message #419651] Mon, 02 June 2008 08:55 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: laurent.legoff.geensy.com

Hi,
Sorry for the 3 days of silence, this was the week-end and the weather
was very nice :-)

In EFS I use java.net.URI because of this class that is declared in the
extension point:

public class PlatformFileSystem extends FileSystem {
/*
* @see
org.eclipse.core.filesystem.provider.FileSystem#getStore(jav a.net.URI)
*/
@Override
public IFileStore getStore(URI uri) {
return new PlatformPluginFileStore(uri);
}
}


I reproduce the problem in AdapterFactoryEditingDomain.isReadOnly()
method see the bug : https://bugs.eclipse.org/bugs/show_bug.cgi?id=235072

is this enough for you to resolve ? Could you please give me a better
solution for this problem ? I didn't look yet at ATTRIBUTE_READ_ONLY !

thanks for comments in code ;-)

bye
Laurent
Re: Add New Resource Storage Mechanism [message #419704 is a reply to message #419676] Mon, 02 June 2008 18:58 Go to previous messageGo to next message
Al B is currently offline Al BFriend
Messages: 130
Registered: July 2009
Senior Member
Hi Laurent,

Thank you for sharing this. I have a few questions. Did you extend or
create your own IContainer? Because the
org.eclipse.core.resources.IContainer does not have a createLink method or
a getFile method that takes a string as parameter.

If that is the case, then I am assuming that from your IContainer is where
you are making usage of your PlatformPluginFileStore class, correct?

Would you mind sharing that code as well?

Thanks!
Re: Add New Resource Storage Mechanism [message #419707 is a reply to message #419704] Tue, 03 June 2008 08:01 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: laurent.legoff.geensy.com

Hi AJ,


> Hi Laurent,
>
> Thank you for sharing this. I have a few questions. Did you extend or
> create your own IContainer? Because the
> org.eclipse.core.resources.IContainer does not have a createLink method
> or a getFile method that takes a string as parameter.
no I don't extend IContainer this class have a getFile(IPath) method and
IProject and IFolder have a getFile(String) that use the other.

>
> If that is the case, then I am assuming that from your IContainer is
> where you are making usage of your PlatformPluginFileStore class,
correct?
>
> Would you mind sharing that code as well?
>
> Thanks!


see below the whole code for filesystem (no problem for sharing this),
this code is usable:


/**
* this fileSystem permit to createLink on resource like
platform:/plugin/project/file.txt
*/
public class PlatformFileSystem extends FileSystem {

/*
* @see
org.eclipse.core.filesystem.provider.FileSystem#getStore(jav a.net.URI)
*/
@Override
public IFileStore getStore(URI uri) {
return new PlatformPluginFileStore(uri);
}

}

/**
* represent a file that have this scheme platform:/ this Store does
not support uri that represent folder.
*/
public class PlatformPluginFileStore extends FileStore {

private static final String[] EMPTY_STRING = new String[] {};
protected URI uri;

public PlatformPluginFileStore(URI uri) {
this.uri = uri;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#fetchInfo(int ,
org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo fetchInfo(int options, IProgressMonitor monitor)
throws CoreException {
// in-lined non-native implementation
FileInfo info = new FileInfo(getName());
info.setExists(true);
info.setDirectory(false);
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, true);
info.setAttribute(EFS.ATTRIBUTE_HIDDEN, false);
return info;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#childNames(in t,
org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public String[] childNames(int options, IProgressMonitor monitor)
throws CoreException {
return EMPTY_STRING;
}

/*
* @see
org.eclipse.core.filesystem.provider.FileStore#getChild(java .lang.String)
*/
@Override
public IFileStore getChild(String name) {
return null;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#getName()
*/
@Override
public String getName() {
String path = uri.getPath();
int lastIndexOf = path.lastIndexOf('/');
if (lastIndexOf >= 0 && lastIndexOf < path.length() - 1) {
return path.substring(lastIndexOf + 1, path.length());
}
return path;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#getParent()
*/
@Override
public IFileStore getParent() {
return null;
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#openInputStre am(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public InputStream openInputStream(int options, IProgressMonitor
monitor) throws CoreException {
try {
return uri.toURL().openStream();
} catch (IOException ex) {
throw new CoreException(new Status(IStatus.ERROR,
Activator.getDefault().getBundle().getSymbolicName(), "Error opening
strean on file",
ex));
}
}

/*
* @see org.eclipse.core.filesystem.provider.FileStore#toURI()
*/
@Override
public URI toURI() {
return uri;
}

}


<plugin>
<extension
point="org.eclipse.core.filesystem.filesystems">
<filesystem
scheme="platform">
<run

class=" com.geensys.ecl.platform.internal.filesystem.PlatformFileSys tem ">
</run>
</filesystem>
</extension>

</plugin>




best regards

Laurent
Re: Add New Resource Storage Mechanism [message #419903 is a reply to message #419639] Thu, 12 June 2008 06:58 Go to previous messageGo to next message
Sven Krause is currently offline Sven KrauseFriend
Messages: 119
Registered: July 2009
Senior Member
Another way is to give the Resource the proper URI on construction. The
generated default editor builds the uri based on the FileEditorInput
(Editor.createModel() -> EditorUIUtil.getURI(getEditorInput())).

And there shall be the origin of the IFile beeing considered:

if (FILE_CLASS != null)
{
IFile file = (IFile)editorInput.getAdapter(FILE_CLASS);
if (file != null)
{
if("file".equalsIgnoreCase(file.getLocationURI().scheme()) { //
consider file origin source
return
URI.createPlatformResourceURI(file.getFullPath().toString(), true);
} else {
return URI.createURI(file.getLocationURI());
}
}


Sven
Re: Add New Resource Storage Mechanism [message #419906 is a reply to message #419903] Thu, 12 June 2008 11:45 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33216
Registered: July 2009
Senior Member
Sven,

Comments below.

Sven Krause wrote:
> Another way is to give the Resource the proper URI on construction.
> The generated default editor builds the uri based on the
> FileEditorInput (Editor.createModel() ->
> EditorUIUtil.getURI(getEditorInput())).
>
> And there shall be the origin of the IFile beeing considered:
>
> if (FILE_CLASS != null)
> {
> IFile file = (IFile)editorInput.getAdapter(FILE_CLASS);
> if (file != null)
> {
> if("file".equalsIgnoreCase(file.getLocationURI().scheme()) {
> // consider file origin source
> return
> URI.createPlatformResourceURI(file.getFullPath().toString(), true);
> } else {
> return URI.createURI(file.getLocationURI());
This approach is "lossy" though. Consider that IWorkspaceRoot has
findFilesForLocationURI and that this returns multiple results. So
while a platform resource URI can be mapped back to the original IFile,
the location URI cannot be uniquely mapped back. Not only that, but our
URI handler for platform resource ensures that the workspace APIs are
accessed for reading, writing, and so on, while returning the location
URI would result in that URI being accessed directly, bypassing the
workspace entirely. I imagine this would result in loss of resource
deltas and proper synchronization.

The platform scheme URL handler really needs to be updated to take the
location URI into account; it's simply broken right now. And we really
need to take advantage of the URI converter's new-to-2.4 direct support
for read only testing...
> }
> }
>
>
> Sven
>
>
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:problems on working working with alternat file system
Next Topic:ECore to MOF XMI and back
Goto Forum:
  


Current Time: Wed Sep 18 21:04:58 GMT 2024

Powered by FUDForum. Page generated in 0.06639 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top