Home » Modeling » EMF » package instance problem - package registry
package instance problem - package registry [message #401209] |
Thu, 18 May 2006 10:47  |
Eclipse User |
|
|
|
Hi,
I have a "rule" file that contains references to the development time ecore files of other models. Later on, this "rule"
is applied on loaded instance models. (sometimes running on code, sometimes dynamic models)
(This is related to a previous thread: "relfection model instance problem")
Now, here is what I do (I don't know if it's the best approach, but it works):
I solve this by loading the rule file twice. The first time, I iterate over the parts referencing the other ecore model
files and do:
resourceSet.getPackageRegistry().put(
usedPackage.eResource().getURI().toString(),
resourceSet.getPackageRegistry().getEPackage(usedPackage.get NsURI().toString()));
- "usedPackage"s reference the other model packages from within the rule file
- Of course, before I make sure that the packages are registered in the resourceSet's package registry under their NsURI
Then, I load the rule file a second time and the correct package instances are used. - Everything works okay so far.
Now, here's where I run into problems: I reference an ecore model file that contains a subpackage:
" ../../../org.eclipse.emf.ocl/model/OCL.ecore#//expressions/V ariable ", then the above mechanism does not work anymore,
because the resource URI-String that I use as a key is (remains)
" platform:/resource/...../org.eclipse.emf.ocl/model/OCL.ecore ", but the usedPackage's nsURI is
"http://www.eclipse.org/OCL2/1.0.0/ocl/expressions"
Any idea on what to register in the package registry now? An how to do this dynamically? Or could you think of any more
convenient way to handle this problem in general?
Thanks for helping
Joel
|
|
|
Re: package instance problem - package registry [message #401210 is a reply to message #401209] |
Thu, 18 May 2006 12:38   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------000705090805040104030104
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Joel,
I'm looking closely at this and it's a bit of a messy problem. :-(
The issue is that the generator intentionally does not generate code for
an EPackage that has no classifiers. So there is no package generated
for the root "ocl" package in OCL.ecore. But the OCL code has stuff like
this to create a root EPackage anyway.
/**
* Root package of the OCL Ecore model, which we have to "fake out"
* because EMF will not generate it.
*/
public static final EPackage OCL_ROOT_PACKAGE;
static {
OCL_ROOT_PACKAGE = EcoreFactory.eINSTANCE.createEPackage();
OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
//$NON-NLS-1$
EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
OCL_ROOT_PACKAGE);
}
/**
* Creates an instance of the model <b>Package </b>, registered with
* {@link org.eclipse.emf.ecore.EPackage.Registry
EPackage.Registry}by the
* package package URI value.
* <p>
* Note: the correct way to create the package is via the static
factory
* method {@link #init init()}, which also performs
initialization of the
* package, or returns the registered package, if one already
exists. <!--
* begin-user-doc --> <!-- end-user-doc -->
*
* @see org.eclipse.emf.ecore.EPackage.Registry
* @see org.eclipse.emf.ocl.expressions.ExpressionsPackage#eNS_URI
* @see #init()
* @generated NOT
*/
private ExpressionsPackageImpl() {
super(eNS_URI, ExpressionsFactory.eINSTANCE);
OCL_ROOT_PACKAGE.getESubpackages().add(this);
}
If it's really important to generate such packages, EMF should probably
be supporting that directly. This is certainly an interesting way of
doing it with far less baggage than creating an actual
OCLPackage/Factory and the associated impls, but there isn't a proper
plugin.xml registration for this "fake" package.
The problem with the above is that the created "ocl" package is not
added to a resource and so this ResourceSetImpl method will return null:
protected Resource delegatedGetResource(URI uri, boolean loadOnDemand)
{
EPackage ePackage =
getPackageRegistry().getEPackage(uri.toString());
return ePackage == null ? null : ePackage.eResource();
}
The following changes would fix that aspect of the problem:
static {
class OCLPackageImpl extends EPackageImpl
{
protected Resource createResource(String uri)
{
return super.createResource(uri);
}
}
OCLPackageImpl oclPackage = new OCLPackageImpl();
OCL_ROOT_PACKAGE = oclPackage;
OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
//$NON-NLS-1$
oclPackage.*createResource*(OCL_ROOT_PACKAGE.getNsURI());
EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
OCL_ROOT_PACKAGE);
}
If that were working correctly, then I believe you should check if the
"usedPackage" is a root (getESuperPackage == null) and only register it
if it is a root. References to that resource should then be redirected
to the root package's resource, which will be able to navigate the
fragment path to the nested packages.
Perhaps you can work around this problem by explicitly creating a
containing resource for the root "ocl" package...
I think we need to revisit this "empty package" issue, i.e., perhaps we
should have a new GenPackage option "to generate even if there are no
classifiers," so please feel free to open an EMF feature request with
the details from this note. Probably the OCL code should be changed as
well, so an OCL bugzilla for that would be good too. I'll talk to
Christian about this...
Joel Greenyer wrote:
> Hi,
> I have a "rule" file that contains references to the development time
> ecore files of other models. Later on, this "rule" is applied on
> loaded instance models. (sometimes running on code, sometimes dynamic
> models)
>
> (This is related to a previous thread: "relfection model instance
> problem")
>
> Now, here is what I do (I don't know if it's the best approach, but it
> works):
> I solve this by loading the rule file twice. The first time, I iterate
> over the parts referencing the other ecore model files and do:
>
> resourceSet.getPackageRegistry().put(
> usedPackage.eResource().getURI().toString(),
> resourceSet.getPackageRegistry().getEPackage(usedPackage.get NsURI().toString()));
>
>
> - "usedPackage"s reference the other model packages from within the
> rule file
> - Of course, before I make sure that the packages are registered in
> the resourceSet's package registry under their NsURI
>
> Then, I load the rule file a second time and the correct package
> instances are used. - Everything works okay so far.
>
> Now, here's where I run into problems: I reference an ecore model file
> that contains a subpackage:
> " ../../../org.eclipse.emf.ocl/model/OCL.ecore#//expressions/V ariable ",
> then the above mechanism does not work anymore, because the resource
> URI-String that I use as a key is (remains)
> " platform:/resource/...../org.eclipse.emf.ocl/model/OCL.ecore ", but
> the usedPackage's nsURI is
> "http://www.eclipse.org/OCL2/1.0.0/ocl/expressions"
>
> Any idea on what to register in the package registry now? An how to do
> this dynamically? Or could you think of any more convenient way to
> handle this problem in general?
>
> Thanks for helping
>
>
> Joel
--------------000705090805040104030104
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Joel,<br>
<br>
I'm looking closely at this and it's a bit of a messy problem. :-( <br>
<br>
The issue is that the generator intentionally does not generate code
for an EPackage that has no classifiers. So there is no package
generated for the root "ocl" package in OCL.ecore. But the OCL code has
stuff like this to create a root EPackage anyway.<br>
<blockquote><small> /**</small><br>
<small> * Root package of the OCL Ecore model, which we have to
"fake out"</small><br>
<small> * because EMF will not generate it.</small><br>
<small> */</small><br>
<small> public static final EPackage OCL_ROOT_PACKAGE;</small><br>
<small> </small><br>
<small> static {</small><br>
<small> OCL_ROOT_PACKAGE =
EcoreFactory.eINSTANCE.createEPackage();</small><br>
<small> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$</small><br>
<small> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$</small><br>
<small>
OCL_ROOT_PACKAGE.setNsURI(<a class="moz-txt-link-rfc2396E" href="http://www.eclipse.org/OCL2/1.0.0/ocl">"http://www.eclipse.org/OCL2/1.0.0/ocl"</a>);
//$NON-NLS-1$</small><br>
<small>
EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
OCL_ROOT_PACKAGE);</small><br>
<small> }</small><br>
<small> </small><br>
<small> /**</small><br>
<small> * Creates an instance of the model <b>Package
</b>, registered with</small><br>
<small> * {@link org.eclipse.emf.ecore.EPackage.Registry
EPackage.Registry}by the</small><br>
<small> * package package URI value.</small><br>
<small> * <p></small><br>
<small> * Note: the correct way to create the package is via the
static factory</small><br>
<small> * method {@link #init init()}, which also performs
initialization of the</small><br>
<small> * package, or returns the registered package, if one
already exists. <!--</small><br>
<small> * begin-user-doc --> <!-- end-user-doc --></small><br>
<small> * </small><br>
<small> * @see org.eclipse.emf.ecore.EPackage.Registry</small><br>
<small> * @see
org.eclipse.emf.ocl.expressions.ExpressionsPackage#eNS_URI</small ><br>
<small> * @see #init()</small><br>
<small> * @generated NOT</small><br>
<small> */</small><br>
<small> private ExpressionsPackageImpl() {</small><br>
<small> super(eNS_URI, ExpressionsFactory.eINSTANCE);</small><br>
<small> </small><br>
<small> OCL_ROOT_PACKAGE.getESubpackages().add(this);</small><br>
<small> }</small><br>
</blockquote>
If it's really important to generate such packages, EMF should probably
be supporting that directly. This is certainly an interesting way of
doing it with far less baggage than creating an actual
OCLPackage/Factory and the associated impls, but there isn't a proper
plugin.xml registration for this "fake" package.<br>
<br>
The problem with the above is that the created "ocl" package is not
added to a resource and so this ResourceSetImpl method will return null:<br>
<blockquote> protected Resource delegatedGetResource(URI uri, boolean
loadOnDemand)<br>
{<br>
EPackage ePackage =
getPackageRegistry().getEPackage(uri.toString());<br>
return ePackage == null ? null : ePackage.eResource();<br>
}<br>
</blockquote>
The following changes would fix that aspect of the problem:<br>
<blockquote><small> static {<br>
class OCLPackageImpl extends EPackageImpl<br>
{<br>
protected Resource createResource(String uri)<br>
{<br>
return super.createResource(uri);<br>
}<br>
}<br>
OCLPackageImpl oclPackage = new OCLPackageImpl();<br>
OCL_ROOT_PACKAGE = oclPackage;<br>
OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$<br>
OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$<br>
OCL_ROOT_PACKAGE.setNsURI(<a class="moz-txt-link-rfc2396E" href="http://www.eclipse.org/OCL2/1.0.0/ocl">"http://www.eclipse.org/OCL2/1.0.0/ocl"</a>);
//$NON-NLS-1$<br>
oclPackage.<b>createResource</b>(OCL_ROOT_PACKAGE.getNsURI()); <br>
EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
OCL_ROOT_PACKAGE);<br>
}</small><br>
</blockquote>
If that were working correctly, then I believe you should check if the
"usedPackage" is a root (getESuperPackage == null) and only register it
if it is a root. References to that resource should then be redirected
to the root package's resource, which will be able to navigate the
fragment path to the nested packages. <br>
<br>
Perhaps you can work around this problem by explicitly creating a
containing resource for the root "ocl" package...<br>
<br>
I think we need to revisit this "empty package" issue, i.e., perhaps we
should have a new GenPackage option "to generate even if there are no
classifiers," so please feel free to open an EMF feature request with
the details from this note. Probably the OCL code should be changed as
well, so an OCL bugzilla for that would be good too. I'll talk to
Christian about this...<br>
<br>
<br>
Joel Greenyer wrote:
<blockquote cite="mide4i1es$s9g$1@utils.eclipse.org" type="cite">Hi,
<br>
I have a "rule" file that contains references to the development time
ecore files of other models. Later on, this "rule" is applied on loaded
instance models. (sometimes running on code, sometimes dynamic models)
<br>
<br>
(This is related to a previous thread: "relfection model instance
problem")
<br>
<br>
Now, here is what I do (I don't know if it's the best approach, but it
works):
<br>
I solve this by loading the rule file twice. The first time, I iterate
over the parts referencing the other ecore model files and do:
<br>
<br>
resourceSet.getPackageRegistry().put(
<br>
usedPackage.eResource().getURI().toString(),
<br>
resourceSet.getPacka geRegistry().getEPackage(usedPackage.getNsURI().toString())) ;
<br>
<br>
- "usedPackage"s reference the other model packages from within the
rule file
<br>
- Of course, before I make sure that the packages are registered in the
resourceSet's package registry under their NsURI
<br>
<br>
Then, I load the rule file a second time and the correct package
instances are used. - Everything works okay so far.
<br>
<br>
Now, here's where I run into problems: I reference an ecore model file
that contains a subpackage:
" ../../../org.eclipse.emf.ocl/model/OCL.ecore#//expressions/V ariable ",
then the above mechanism does not work anymore, because the resource
URI-String that I use as a key is (remains)
" platform:/resource/...../org.eclipse.emf.ocl/model/OCL.ecore ", but the
usedPackage's nsURI is
<a class="moz-txt-link-rfc2396E" href="http://www.eclipse.org/OCL2/1.0.0/ocl/expressions">"http://www.eclipse.org/OCL2/1.0.0/ocl/expressions"</a>
<br>
<br>
Any idea on what to register in the package registry now? An how to do
this dynamically? Or could you think of any more convenient way to
handle this problem in general?
<br>
<br>
Thanks for helping
<br>
<br>
<br>
Joel
<br>
</blockquote>
<br>
</body>
</html>
--------------000705090805040104030104--
|
|
|
Re: package instance problem - package registry [message #401215 is a reply to message #401210] |
Thu, 18 May 2006 14:59   |
Eclipse User |
|
|
|
Originally posted by: cdamus.ca.ibm.com
Hi, Joel, Ed,
I have raised https://bugs.eclipse.org/bugs/show_bug.cgi?id=142572 to
address this problem.
Thanks for pointing it out!
Christian
Ed Merks wrote:
> Joel,
>
> I'm looking closely at this and it's a bit of a messy problem. :-(
>
> The issue is that the generator intentionally does not generate code for
> an EPackage that has no classifiers. So there is no package generated
> for the root "ocl" package in OCL.ecore. But the OCL code has stuff like
> this to create a root EPackage anyway.
>
> /**
> * Root package of the OCL Ecore model, which we have to "fake
> out" * because EMF will not generate it.
> */
> public static final EPackage OCL_ROOT_PACKAGE;
>
> static {
> OCL_ROOT_PACKAGE = EcoreFactory.eINSTANCE.createEPackage();
> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
>
> OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
> //$NON-NLS-1$
> EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
> OCL_ROOT_PACKAGE);
> }
>
> /**
> * Creates an instance of the model <b>Package </b>, registered
> with * {@link org.eclipse.emf.ecore.EPackage.Registry
> EPackage.Registry}by the
> * package package URI value.
> * <p>
> * Note: the correct way to create the package is via the static
> factory
> * method {@link #init init()}, which also performs
> initialization of the
> * package, or returns the registered package, if one already
> exists. <!--
> * begin-user-doc --> <!-- end-user-doc -->
> *
> * @see org.eclipse.emf.ecore.EPackage.Registry
> * @see org.eclipse.emf.ocl.expressions.ExpressionsPackage#eNS_URI
> * @see #init()
> * @generated NOT
> */
> private ExpressionsPackageImpl() {
> super(eNS_URI, ExpressionsFactory.eINSTANCE);
>
> OCL_ROOT_PACKAGE.getESubpackages().add(this);
> }
>
> If it's really important to generate such packages, EMF should probably
> be supporting that directly. This is certainly an interesting way of
> doing it with far less baggage than creating an actual
> OCLPackage/Factory and the associated impls, but there isn't a proper
> plugin.xml registration for this "fake" package.
<snip>
|
|
|
Re: package instance problem - package registry [message #401243 is a reply to message #401210] |
Fri, 19 May 2006 13:26   |
Eclipse User |
|
|
|
Hi Ed,
this is an interesting insight to EMF internals. With the suggested additions to the ExpressionsPackageImpl and your
suggested strategy on registering the packages, it works fine. So thanks a lot! With the bugzilla entry from Christian,
I hope that this will find its way into the OCL build soon.
I agree with you that empty packages should be generated the same way as non-empty packages. That could save the
workaround in these rare cases. I don't know where that extra "baggage" would make a problem. In my opinion, the extra
GenPackage option that you suggested ("generate even if has no classifiers") could even be "true" by default.
Joel
Ed Merks wrote:
> Joel,
>
> I'm looking closely at this and it's a bit of a messy problem. :-(
>
> The issue is that the generator intentionally does not generate code for
> an EPackage that has no classifiers. So there is no package generated
> for the root "ocl" package in OCL.ecore. But the OCL code has stuff like
> this to create a root EPackage anyway.
>
> /**
> * Root package of the OCL Ecore model, which we have to "fake out"
> * because EMF will not generate it.
> */
> public static final EPackage OCL_ROOT_PACKAGE;
>
> static {
> OCL_ROOT_PACKAGE = EcoreFactory.eINSTANCE.createEPackage();
> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
>
> OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
> //$NON-NLS-1$
> EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
> OCL_ROOT_PACKAGE);
> }
>
> /**
> * Creates an instance of the model <b>Package </b>, registered with
> * {@link org.eclipse.emf.ecore.EPackage.Registry
> EPackage.Registry}by the
> * package package URI value.
> * <p>
> * Note: the correct way to create the package is via the static
> factory
> * method {@link #init init()}, which also performs
> initialization of the
> * package, or returns the registered package, if one already
> exists. <!--
> * begin-user-doc --> <!-- end-user-doc -->
> *
> * @see org.eclipse.emf.ecore.EPackage.Registry
> * @see org.eclipse.emf.ocl.expressions.ExpressionsPackage#eNS_URI
> * @see #init()
> * @generated NOT
> */
> private ExpressionsPackageImpl() {
> super(eNS_URI, ExpressionsFactory.eINSTANCE);
>
> OCL_ROOT_PACKAGE.getESubpackages().add(this);
> }
>
> If it's really important to generate such packages, EMF should probably
> be supporting that directly. This is certainly an interesting way of
> doing it with far less baggage than creating an actual
> OCLPackage/Factory and the associated impls, but there isn't a proper
> plugin.xml registration for this "fake" package.
>
> The problem with the above is that the created "ocl" package is not
> added to a resource and so this ResourceSetImpl method will return null:
>
> protected Resource delegatedGetResource(URI uri, boolean loadOnDemand)
> {
> EPackage ePackage =
> getPackageRegistry().getEPackage(uri.toString());
> return ePackage == null ? null : ePackage.eResource();
> }
>
> The following changes would fix that aspect of the problem:
>
> static {
> class OCLPackageImpl extends EPackageImpl
> {
> protected Resource createResource(String uri)
> {
> return super.createResource(uri);
> }
> }
> OCLPackageImpl oclPackage = new OCLPackageImpl();
> OCL_ROOT_PACKAGE = oclPackage;
> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
>
> OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
> //$NON-NLS-1$
> oclPackage.*createResource*(OCL_ROOT_PACKAGE.getNsURI());
> EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
> OCL_ROOT_PACKAGE);
> }
>
> If that were working correctly, then I believe you should check if the
> "usedPackage" is a root (getESuperPackage == null) and only register it
> if it is a root. References to that resource should then be redirected
> to the root package's resource, which will be able to navigate the
> fragment path to the nested packages.
>
> Perhaps you can work around this problem by explicitly creating a
> containing resource for the root "ocl" package...
>
> I think we need to revisit this "empty package" issue, i.e., perhaps we
> should have a new GenPackage option "to generate even if there are no
> classifiers," so please feel free to open an EMF feature request with
> the details from this note. Probably the OCL code should be changed as
> well, so an OCL bugzilla for that would be good too. I'll talk to
> Christian about this...
>
>
> Joel Greenyer wrote:
>> Hi,
>> I have a "rule" file that contains references to the development time
>> ecore files of other models. Later on, this "rule" is applied on
>> loaded instance models. (sometimes running on code, sometimes dynamic
>> models)
>>
>> (This is related to a previous thread: "relfection model instance
>> problem")
>>
>> Now, here is what I do (I don't know if it's the best approach, but it
>> works):
>> I solve this by loading the rule file twice. The first time, I iterate
>> over the parts referencing the other ecore model files and do:
>>
>> resourceSet.getPackageRegistry().put(
>> usedPackage.eResource().getURI().toString(),
>> resourceSet.getPackageRegistry().getEPackage(usedPackage.get NsURI().toString()));
>>
>>
>> - "usedPackage"s reference the other model packages from within the
>> rule file
>> - Of course, before I make sure that the packages are registered in
>> the resourceSet's package registry under their NsURI
>>
>> Then, I load the rule file a second time and the correct package
>> instances are used. - Everything works okay so far.
>>
>> Now, here's where I run into problems: I reference an ecore model file
>> that contains a subpackage:
>> " ../../../org.eclipse.emf.ocl/model/OCL.ecore#//expressions/V ariable ",
>> then the above mechanism does not work anymore, because the resource
>> URI-String that I use as a key is (remains)
>> " platform:/resource/...../org.eclipse.emf.ocl/model/OCL.ecore ", but
>> the usedPackage's nsURI is
>> "http://www.eclipse.org/OCL2/1.0.0/ocl/expressions"
>>
>> Any idea on what to register in the package registry now? An how to do
>> this dynamically? Or could you think of any more convenient way to
>> handle this problem in general?
>>
>> Thanks for helping
>>
>>
>> Joel
>
|
|
|
Re: package instance problem - package registry [message #401246 is a reply to message #401243] |
Fri, 19 May 2006 14:37   |
Eclipse User |
|
|
|
Joel,
Either your or Christian should open a feature request for this or we'll
forget and it won't get done...
Joel Greenyer wrote:
> Hi Ed,
> this is an interesting insight to EMF internals. With the suggested
> additions to the ExpressionsPackageImpl and your suggested strategy on
> registering the packages, it works fine. So thanks a lot! With the
> bugzilla entry from Christian, I hope that this will find its way into
> the OCL build soon.
>
> I agree with you that empty packages should be generated the same way
> as non-empty packages. That could save the workaround in these rare
> cases. I don't know where that extra "baggage" would make a problem.
> In my opinion, the extra GenPackage option that you suggested
> ("generate even if has no classifiers") could even be "true" by default.
>
>
> Joel
>
> Ed Merks wrote:
>> Joel,
>>
>> I'm looking closely at this and it's a bit of a messy problem. :-(
>>
>> The issue is that the generator intentionally does not generate code
>> for an EPackage that has no classifiers. So there is no package
>> generated for the root "ocl" package in OCL.ecore. But the OCL code
>> has stuff like this to create a root EPackage anyway.
>>
>> /**
>> * Root package of the OCL Ecore model, which we have to
>> "fake out"
>> * because EMF will not generate it.
>> */
>> public static final EPackage OCL_ROOT_PACKAGE;
>> static {
>> OCL_ROOT_PACKAGE = EcoreFactory.eINSTANCE.createEPackage();
>> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
>> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
>>
>> OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
>> //$NON-NLS-1$
>> EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
>> OCL_ROOT_PACKAGE);
>> }
>> /**
>> * Creates an instance of the model <b>Package </b>,
>> registered with
>> * {@link org.eclipse.emf.ecore.EPackage.Registry
>> EPackage.Registry}by the
>> * package package URI value.
>> * <p>
>> * Note: the correct way to create the package is via the static
>> factory
>> * method {@link #init init()}, which also performs
>> initialization of the
>> * package, or returns the registered package, if one already
>> exists. <!--
>> * begin-user-doc --> <!-- end-user-doc -->
>> *
>> * @see org.eclipse.emf.ecore.EPackage.Registry
>> * @see
>> org.eclipse.emf.ocl.expressions.ExpressionsPackage#eNS_URI
>> * @see #init()
>> * @generated NOT
>> */
>> private ExpressionsPackageImpl() {
>> super(eNS_URI, ExpressionsFactory.eINSTANCE);
>> OCL_ROOT_PACKAGE.getESubpackages().add(this);
>> }
>>
>> If it's really important to generate such packages, EMF should
>> probably be supporting that directly. This is certainly an
>> interesting way of doing it with far less baggage than creating an
>> actual OCLPackage/Factory and the associated impls, but there isn't a
>> proper plugin.xml registration for this "fake" package.
>>
>> The problem with the above is that the created "ocl" package is not
>> added to a resource and so this ResourceSetImpl method will return null:
>>
>> protected Resource delegatedGetResource(URI uri, boolean
>> loadOnDemand)
>> {
>> EPackage ePackage =
>> getPackageRegistry().getEPackage(uri.toString());
>> return ePackage == null ? null : ePackage.eResource();
>> }
>>
>> The following changes would fix that aspect of the problem:
>>
>> static {
>> class OCLPackageImpl extends EPackageImpl
>> {
>> protected Resource createResource(String uri)
>> {
>> return super.createResource(uri);
>> }
>> }
>> OCLPackageImpl oclPackage = new OCLPackageImpl();
>> OCL_ROOT_PACKAGE = oclPackage;
>> OCL_ROOT_PACKAGE.setName("ocl"); //$NON-NLS-1$
>> OCL_ROOT_PACKAGE.setNsPrefix("ocl"); //$NON-NLS-1$
>>
>> OCL_ROOT_PACKAGE.setNsURI("http://www.eclipse.org/OCL2/1.0.0/ocl");
>> //$NON-NLS-1$
>> oclPackage.*createResource*(OCL_ROOT_PACKAGE.getNsURI());
>> EPackage.Registry.INSTANCE.put(OCL_ROOT_PACKAGE.getNsURI(),
>> OCL_ROOT_PACKAGE);
>> }
>>
>> If that were working correctly, then I believe you should check if
>> the "usedPackage" is a root (getESuperPackage == null) and only
>> register it if it is a root. References to that resource should then
>> be redirected to the root package's resource, which will be able to
>> navigate the fragment path to the nested packages.
>>
>> Perhaps you can work around this problem by explicitly creating a
>> containing resource for the root "ocl" package...
>>
>> I think we need to revisit this "empty package" issue, i.e., perhaps
>> we should have a new GenPackage option "to generate even if there are
>> no classifiers," so please feel free to open an EMF feature request
>> with the details from this note. Probably the OCL code should be
>> changed as well, so an OCL bugzilla for that would be good too. I'll
>> talk to Christian about this...
>>
>>
>> Joel Greenyer wrote:
>>> Hi,
>>> I have a "rule" file that contains references to the development
>>> time ecore files of other models. Later on, this "rule" is applied
>>> on loaded instance models. (sometimes running on code, sometimes
>>> dynamic models)
>>>
>>> (This is related to a previous thread: "relfection model instance
>>> problem")
>>>
>>> Now, here is what I do (I don't know if it's the best approach, but
>>> it works):
>>> I solve this by loading the rule file twice. The first time, I
>>> iterate over the parts referencing the other ecore model files and do:
>>>
>>> resourceSet.getPackageRegistry().put(
>>> usedPackage.eResource().getURI().toString(),
>>>
>>> resourceSet.getPackageRegistry().getEPackage(usedPackage.get NsURI().toString()));
>>>
>>>
>>> - "usedPackage"s reference the other model packages from within the
>>> rule file
>>> - Of course, before I make sure that the packages are registered in
>>> the resourceSet's package registry under their NsURI
>>>
>>> Then, I load the rule file a second time and the correct package
>>> instances are used. - Everything works okay so far.
>>>
>>> Now, here's where I run into problems: I reference an ecore model
>>> file that contains a subpackage:
>>> " ../../../org.eclipse.emf.ocl/model/OCL.ecore#//expressions/V ariable ",
>>> then the above mechanism does not work anymore, because the resource
>>> URI-String that I use as a key is (remains)
>>> " platform:/resource/...../org.eclipse.emf.ocl/model/OCL.ecore ", but
>>> the usedPackage's nsURI is
>>> "http://www.eclipse.org/OCL2/1.0.0/ocl/expressions"
>>>
>>> Any idea on what to register in the package registry now? An how to
>>> do this dynamically? Or could you think of any more convenient way
>>> to handle this problem in general?
>>>
>>> Thanks for helping
>>>
>>>
>>> Joel
>>
|
|
| |
Goto Forum:
Current Time: Sun Aug 03 17:56:06 EDT 2025
Powered by FUDForum. Page generated in 0.04477 seconds
|