| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.felix.http.jetty.internal.webapp; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.Enumeration; |
| |
| import org.eclipse.jetty.util.URIUtil; |
| import org.eclipse.jetty.util.resource.Resource; |
| import org.eclipse.jetty.util.resource.URLResource; |
| import org.eclipse.jetty.webapp.WebAppContext; |
| import org.osgi.framework.Bundle; |
| |
| public class WebAppBundleContext extends WebAppContext |
| { |
| public WebAppBundleContext(String contextPath, final Bundle bundle, final ClassLoader parent) |
| { |
| super(null, contextPath.substring(1), contextPath); |
| |
| this.setBaseResource(new BundleURLResource(bundle.getEntry("/"))); |
| this.setClassLoader(new ClassLoader(parent) |
| { |
| @Override |
| protected Class<?> findClass(String s) throws ClassNotFoundException |
| { |
| // Don't try to load classes from the bundle when it is not active |
| if (bundle.getState() == Bundle.ACTIVE) |
| { |
| try |
| { |
| return bundle.loadClass(s); |
| } |
| catch (ClassNotFoundException e) |
| { |
| } |
| } |
| return super.findClass(s); |
| } |
| |
| @Override |
| protected URL findResource(String name) |
| { |
| // Don't try to load resources from the bundle when it is not active |
| if (bundle.getState() == Bundle.ACTIVE) |
| { |
| URL url = bundle.getResource(name); |
| if (url != null) |
| { |
| return url; |
| } |
| } |
| return super.findResource(name); |
| } |
| |
| @Override |
| protected Enumeration<URL> findResources(String name) throws IOException |
| { |
| // Don't try to load resources from the bundle when it is not active |
| if (bundle.getState() == Bundle.ACTIVE) |
| { |
| Enumeration<URL> urls = bundle.getResources(name); |
| if (urls != null) |
| { |
| return urls; |
| } |
| } |
| return super.findResources(name); |
| } |
| }); |
| this.setThrowUnavailableOnStartupException(true); |
| } |
| |
| @Override |
| public Resource newResource(URL url) throws IOException |
| { |
| if (url == null) |
| { |
| return null; |
| } |
| return new BundleURLResource(url); |
| } |
| |
| static class BundleURLResource extends URLResource |
| { |
| BundleURLResource(URL url) |
| { |
| super(url, null); |
| } |
| |
| @Override |
| public synchronized void close() |
| { |
| if (this._in != null) |
| { |
| // Do not close this input stream: it would invalidate |
| // the associated zipfile's inflater and every future access |
| // to some bundle entry leads to an NPE with message |
| // "Inflater has been closed" |
| this._in = null; |
| } |
| super.close(); |
| } |
| |
| @Override |
| public Resource addPath(String path) throws MalformedURLException |
| { |
| if (path == null) |
| { |
| return null; |
| } |
| path = URIUtil.canonicalPath(path); |
| |
| URL url = new URL(URIUtil.addPaths(this._url.toExternalForm(), path)); |
| return new BundleURLResource(url); |
| } |
| |
| @Override |
| public File getFile() throws IOException |
| { |
| // not available as a file |
| return null; |
| } |
| } |
| } |