1 package org
.argeo
.cms
.servlet
.internal
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.net
.FileNameMap
;
7 import java
.net
.URLConnection
;
8 import java
.util
.Collection
;
9 import java
.util
.SortedMap
;
10 import java
.util
.TreeMap
;
12 import javax
.servlet
.ServletException
;
13 import javax
.servlet
.http
.HttpServlet
;
14 import javax
.servlet
.http
.HttpServletRequest
;
15 import javax
.servlet
.http
.HttpServletResponse
;
17 import org
.argeo
.cms
.osgi
.FilterRequirement
;
18 import org
.argeo
.cms
.osgi
.PublishNamespace
;
19 import org
.argeo
.cms
.util
.StreamUtils
;
20 import org
.osgi
.framework
.Bundle
;
21 import org
.osgi
.framework
.BundleContext
;
22 import org
.osgi
.framework
.FrameworkUtil
;
23 import org
.osgi
.framework
.Version
;
24 import org
.osgi
.framework
.VersionRange
;
25 import org
.osgi
.framework
.namespace
.PackageNamespace
;
26 import org
.osgi
.framework
.wiring
.BundleCapability
;
27 import org
.osgi
.framework
.wiring
.BundleWiring
;
28 import org
.osgi
.framework
.wiring
.FrameworkWiring
;
29 import org
.osgi
.resource
.Requirement
;
32 * Publishes client-side web resources (JavaScript, HTML, CSS, images, etc.)
33 * from the OSGi runtime.
35 public class PkgServlet
extends HttpServlet
{
36 private static final long serialVersionUID
= 7660824185145214324L;
38 private static FileNameMap fileNameMap
= URLConnection
.getFileNameMap();
40 private BundleContext bundleContext
= FrameworkUtil
.getBundle(PkgServlet
.class).getBundleContext();
43 protected void doGet(HttpServletRequest req
, HttpServletResponse resp
) throws ServletException
, IOException
{
44 String pathInfo
= req
.getPathInfo();
46 String pkg
, versionStr
, file
;
47 String
[] parts
= pathInfo
.split("/");
48 // first is always empty
49 if (parts
.length
== 4) {
51 versionStr
= parts
[2];
53 } else if (parts
.length
== 3) {
58 throw new IllegalArgumentException("Unsupported path length " + pathInfo
);
62 String contentType
= fileNameMap
.getContentTypeFor(file
);
63 resp
.setContentType(contentType
);
65 FrameworkWiring frameworkWiring
= bundleContext
.getBundle(0).adapt(FrameworkWiring
.class);
67 if (versionStr
== null) {
68 filter
= "(" + PackageNamespace
.PACKAGE_NAMESPACE
+ "=" + pkg
+ ")";
70 if (versionStr
.startsWith("[") || versionStr
.startsWith("(")) {// range
71 VersionRange versionRange
= new VersionRange(versionStr
);
72 filter
= "(&(" + PackageNamespace
.PACKAGE_NAMESPACE
+ "=" + pkg
+ ")"
73 + versionRange
.toFilterString(PackageNamespace
.CAPABILITY_VERSION_ATTRIBUTE
) + ")";
76 Version version
= new Version(versionStr
);
77 filter
= "(&(" + PackageNamespace
.PACKAGE_NAMESPACE
+ "=" + pkg
+ ")("
78 + PackageNamespace
.CAPABILITY_VERSION_ATTRIBUTE
+ "=" + version
+ "))";
81 Requirement requirement
= new FilterRequirement(PackageNamespace
.PACKAGE_NAMESPACE
, filter
);
82 Collection
<BundleCapability
> packages
= frameworkWiring
.findProviders(requirement
);
83 if (packages
.isEmpty()) {
88 // TODO verify that it works with multiple versions
89 SortedMap
<Version
, BundleCapability
> sorted
= new TreeMap
<>();
90 for (BundleCapability capability
: packages
) {
91 sorted
.put(capability
.getRevision().getVersion(), capability
);
94 Bundle bundle
= sorted
.get(sorted
.firstKey()).getRevision().getBundle();
95 String entryPath
= '/' + pkg
.replace('.', '/') + '/' + file
;
96 URL internalURL
= bundle
.getResource(entryPath
);
97 if (internalURL
== null) {
102 // Resource found, we now check whether it can be published
103 boolean publish
= false;
104 BundleWiring bundleWiring
= bundle
.adapt(BundleWiring
.class);
105 capabilities
: for (BundleCapability bundleCapability
: bundleWiring
106 .getCapabilities(PublishNamespace
.CMS_PUBLISH_NAMESPACE
)) {
107 Object publishedPkg
= bundleCapability
.getAttributes().get(PublishNamespace
.PKG
);
108 if (publishedPkg
!= null) {
109 if (publishedPkg
.equals("*") || publishedPkg
.equals(pkg
)) {
110 Object publishedFile
= bundleCapability
.getAttributes().get(PublishNamespace
.FILE
);
111 if (publishedFile
== null) {
115 String
[] publishedFiles
= publishedFile
.toString().split(",");
116 for (String pattern
: publishedFiles
) {
117 if (pattern
.startsWith("*.")) {
118 String ext
= pattern
.substring(1);
119 if (file
.endsWith(ext
)) {
124 if (publishedFile
.equals(file
)) {
140 try (InputStream in
= internalURL
.openStream()) {
141 StreamUtils
.copy(in
, resp
.getOutputStream());