blob: 434ffdb3340aeac9d682a92f590daa80e8eec0cb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 SAP SE
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* Violeta Georgieva - initial contribution
*******************************************************************************/
package org.eclipse.gemini.web.tomcat.internal.bundleresources;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
import org.apache.catalina.Host;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.webresources.EmptyResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import org.osgi.framework.Bundle;
public class BundleWebResourceRoot extends StandardRoot {
private final Bundle bundle;
private final WebResource main;
private Path docBase;
public BundleWebResourceRoot(Bundle bundle, String docBaseStr) {
this.bundle = bundle;
this.main = new BundleWebResource(this.bundle, this);
if (docBaseStr != null) {
this.docBase = Paths.get(docBaseStr);
if (!this.docBase.isAbsolute()) {
this.docBase = Paths.get(((Host) getContext().getParent()).getAppBaseFile().getPath()).resolve(this.docBase);
}
}
}
@Override
public void createWebResourceSet(ResourceSetType type, String webAppMount, URL url, String internalPath) {
BaseLocation baseLocation = new BaseLocation(url);
createWebResourceSet(type, webAppMount, baseLocation.getBasePath(), baseLocation.getArchivePath(), internalPath);
}
@Override
public void createWebResourceSet(ResourceSetType type, String webAppMount, String base, String archivePath, String internalPath) {
WebResourceSet resourceSet = null;
if (base.startsWith("bundleentry")) {
if (archivePath != null) {
if (archivePath.toLowerCase(Locale.ENGLISH).endsWith(".jar")) {
resourceSet = new BundleJarResourceSet(this, webAppMount, base + archivePath, internalPath);
} else {
WebResource entry = ((BundleWebResource) this.main).getNamedEntry(archivePath).getKey();
if (entry != null) {
resourceSet = new BundleWebResourceSet(entry, this, webAppMount, this.docBase.toAbsolutePath().toString() + archivePath,
internalPath);
}
}
if (type.equals(ResourceSetType.CLASSES_JAR)) {
resourceSet.setClassLoaderOnly(true);
}
}
} else {
// TODO need additional testing
WebResource entry = ((BundleWebResource) this.main).getNamedEntry(base).getKey();
if (entry != null) {
resourceSet = new BundleWebResourceSet(entry, this, webAppMount, base, internalPath);
if (type.equals(ResourceSetType.CLASSES_JAR)) {
resourceSet.setClassLoaderOnly(true);
}
}
}
if (resourceSet != null) {
switch (type) {
case PRE:
addPreResources(resourceSet);
break;
case CLASSES_JAR:
addClassResources(resourceSet);
break;
case RESOURCE_JAR:
addJarResources(resourceSet);
break;
case POST:
addPostResources(resourceSet);
break;
default:
throw new IllegalArgumentException("Unable to create WebResourceSet of unknown type [" + type + "].");
}
}
}
@Override
protected String getObjectNameKeyProperties() {
StringBuilder keyProperties = new StringBuilder("type=BundleWebResourceRoot");
keyProperties.append(getContext().getMBeanKeyProperties());
return keyProperties.toString();
}
@Override
protected void registerURLStreamHandlerFactory() {
// no-op
}
@Override
protected WebResourceSet createMainResourceSet() {
WebResourceSet mainResourceSet;
if (this.docBase == null) {
// TODO When we are in not Equinox case the docBase will be null
// we need to handle this case also
mainResourceSet = new EmptyResourceSet(this);
} else {
mainResourceSet = new BundleWebResourceSet(this.main, this, "/", this.docBase.toAbsolutePath().toString(), "/");
}
return mainResourceSet;
}
private static class BaseLocation {
private String basePath = "";
private String archivePath = "";
BaseLocation(URL url) {
if ("jar".equals(url.getProtocol())) {
String jarUrl = url.toString();
int endOfFileUrl = jarUrl.indexOf("!/");
String fileUrl = jarUrl.substring(4, endOfFileUrl);
if (fileUrl.startsWith("bundleentry")) {
URL file = null;
try {
file = new URL(fileUrl);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
this.archivePath = file.getFile();
this.basePath = fileUrl.substring(0, fileUrl.indexOf(this.archivePath));
}
} else if ("bundleentry".equals(url.getProtocol())) {
this.archivePath = url.getFile();
String fileUrl = url.toString();
this.basePath = fileUrl.substring(0, fileUrl.indexOf(this.archivePath));
} else {
throw new IllegalArgumentException("The URL protocol [" + url.getProtocol()
+ "] is not supported by this web resources implementation");
}
}
String getBasePath() {
return this.basePath;
}
String getArchivePath() {
return this.archivePath;
}
}
}