/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.engage.theodul.manager.impl;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
/**
* A Classloader that loads resources from a bundle or from a directory in the
* filesystem. The files from the filesystem take precedence over the files from
* the bundle.
*/
public class StaticResourceClassloader extends ClassLoader {
private static final Logger logger = LoggerFactory.getLogger(EngagePluginManagerImpl.class);
private final Bundle bundle; // Bundle to load resources from
private final File overrideDir; // Override directory
private final String bundlePathPrefix; // prefix path in bundle resources
public StaticResourceClassloader(Bundle bundle, File overrideDir, String bundleResourcePath) {
super();
this.bundle = bundle;
this.overrideDir = overrideDir;
this.bundlePathPrefix = bundleResourcePath;
logger.info("Bundle={} Override={}", bundle.getSymbolicName(), this.overrideDir.getAbsolutePath());
}
@Override
public URL getResource(String path) {
// check if override dir is sane. doing this every time so that override
// directory is optional and can be created during runtime.
if (overrideIsSane()) {
// try to find resource in override dir
String fspath = path.replaceAll("../", "");
fspath = fspath.replace(bundlePathPrefix, "");
File file = new File(overrideDir.getAbsoluteFile() + File.separator + fspath);
if (file.exists() && file.isFile()) {
try {
logger.debug("Resource from filesystem overrides bundle resource: {}", file.getAbsolutePath());
return file.toURI().toURL();
} catch (MalformedURLException e) {
logger.error("Failed to get filesystem URL for override file! ", e);
}
}
}
// if we did not find the resource in filesystem, try to get it from the bundle
URL out = bundle.getResource(path);
logger.debug("Serving resource from bundle: {}", out);
return out;
}
/**
* Tests if the specified filesystem path is an existing readable directory.
*
* @return true, iff override path is an existing, readable directory; false
* otherwise
*/
public boolean overrideIsSane() {
return overrideDir.exists() && overrideDir.isDirectory() && overrideDir.canRead();
}
}