Great post.
For structuring your URL space I'm a little bit torn -- I
really think we can write version aware _javascript_ applications capable of
dynamically finding the correct URLs, but for now...
...a technique
I've used for handling multiple versions of a js library based
around the use of URLs relative to an application
base.
{Hopefully this isn't too cryptic}
Basically, I create one bundle that holds nothing but
http.registry extensions that together define an
application.
To get a flavour of the approach I've
tweaked your example... ( I'm hoping we could remove the version from the path in
the bundle)
<extension
point="org.eclipse.equinox.http.registry.resources">
<resource
alias="myapp/dojo" base-name="/dojo-ajax"
context-name="myapp"/>
</extension>
and then in the context of myapp (e.g. in
myapp/index.html) use a relative URL:
<script type="text/_javascript_"
src=""></script>
In some situations adding a prefix dynamically
like Jochen suggests is required, however if at all possible I prefer using relative URLs as it will
work with static pages.
--
http.registry provides an "httpcontexts"
extension-point however one real challenge
with the approach is that the default implementation only lets you gather
resources from the bundle where the extension is defined. To date I've
handled this by defining "httpcontexts" and their contributions in the various
originating bundles however I've never really liked this. Your post's use
of Require-Bundle might be a way forward.
We could add a "bundle" parameter to the httpcontexts
extension
e.g.
<extension
point="org.eclipse.equinox.http.registry.httpcontexts">
<httpcontext name="myapp"
path="/" bundle="org.dojotoolkit.js" />
</extension>
The use of bundle
would necessitate a "Require-Bundle" in the declaring bundles manifest so that
the internals of http.registry could do a lookup using PackageAdmin to track down the
correct RequiredBundle.
I'll open a bug to consider.
-Simon
Hi Jeff,
On 11/6/06, Jeff
McAffer <Jeff_McAffer@xxxxxxxxxx>
wrote:
Recently there was a bug report about some dojo stuff
not working well with our http service. That prompted me to try it out
and indeed there is a problem. In any event, in the process of trying
this I got dojo and started to play. I was not happy with the idea
that I would put the dojo libs in my actual application bundle since many
different apps deployed to the same server might use dojo.
Furthermore, I assume that browsers are not smart enough to handle the
same libs at many different URLs in any sort of optimal way. So I make
a dojo bundle that included
<extension point="org.eclipse.equinox.http.registry.resources">
<resource alias="/dojo"
base-name="/dojo-0.4.0-ajax"/>
</extension>
Now an dojo-based bundle can contribute content wherever it wants and
include something like
<script type="text/_javascript_"
src=""></script>
This seems to work fine.
I agree: This should be the target scenario, to support building
reusable components, in respect to restricted resources.
This got me to thinking about modularized, non-Java
web content. For example, what if there are multiple versions of dojo
on the server and different apps that need the different dojo versions.
We could have declared the dojo alias to be /dojo-0.4.0 and have apps
reference it but then the app would be tightly bound to that version of
dojo.
Then I though of having
some sort of variable that would be bound to the right version of dojo.
for example,
<script type="text/_javascript_"
src=""></script>
and then dojo_base is set to the appropriate URL
fragment. This is better but in and of itself feels quite brittle and
would require quite a bit of maintenance.
You are completely right.
So then I thought, is there some way we can use the
OSGi dependency mechanism to handle this? For example, I have a dojo
bundle (called "dojo" with version 0.4.0 that surfaces the dojo function at
a particular (set of) URL. My application bundle could spec a
dependency
Require-Bundle: dojo; version=[0.4.0,0.5.0)
(whatever)
and then if we
could manage to have the dojo references in my app's content replaced with
the appropriate references as surfaced by the dojo bundle, we'd be
rockin.
In a certain light this
is like having a dojo service registered in URL space and wanting to access
it from HTML/_javascript_ content.
Is there any precedence for this? Other systems
that do such things? mechanisms that we could leverage? Is this
just a goofy idea?
We are using a component based platform
including UI resources. We achieve this behaviour this way: the service
provider is registering its resources (in this case: a tupel of an unique ID
and the corresponding URL, e.g. in your case "url.dojo.base" to "/dojo", or
"/dojo-0.4.0-ajax"). The services which refers to this resources will look up
the unique ID to the registered URL.
We do it in a proprietary way. In
OSGi context, this could be done via some kind of registry. Lets assume the
http.registry component will provide an additional extension point, where the
service provider can register its "public resources", e.g.
<extension
point="org.eclipse.equinox.http.registry.url ">
<url id="url.dojo"
url=""/>
</extension>
Note: The <resource alias="/dojo" base-name="/dojo-0.4.0-ajax"/>
should not be used, as alias is the public URL seen by browser, but should not
be used as identifier. It is also possible, that only specific parts of the
resources should be made public viewable.
The "http.registry" bundle could provide a service (like
"NamedHttpContextService) e.g. "URLResolverService", which can look up the ID
to the corresponding URL (or provide a static helper method, for simple
access).
For your scenario regarding script variables:
typically a web application can store some values within its web container,
e.g. referring attributes in ServletContext. The bundle "http.service" is just
supporting this (but not yet used, or ?). If the " http.registry" bundle would
propagate these URL's in some way (e.g. key is uniqueID, value is the URL) to
the servlet context, a JSP could refer to it using standard language
features:
<%
String
dojo_base =
request.getSession().getServletContext().getAttribute("url.dojo");
%>
This can be made configurable via extension point:
<extension
point="org.eclipse.equinox.http.registry.url ">
<url id="url.dojo"
url="" addToServletContext="true" />
</extension>
This would need
additional implementation in Eclipse based HTTP service, as navigation from
HttpSession to HttpServletContext is not yet supported (due to Servlet-API 2.1
only support).
From my point of view, such a "plugin" concept for UI
resources would be a necessary mechanism to build UI components. I strongly
support your idea !
Jochen