blob: af1dc41607e8280be959d3c812ed656be12aae85 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 SAP AG
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial contribution
*******************************************************************************/
package org.eclipse.virgo.web.enterprise.persistence.openejb.classloading.hook;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
import org.eclipse.osgi.internal.hookregistry.HookRegistry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
public class AppLoaderClasspathExtenderClassLoadingHook extends ClassLoaderHook implements HookConfigurator {
File persistenceIntegrationJar = null;
private static final String FILE_SCHEME = "file:";
private static final String WEB_CONTEXTPATH_HEADER = "Web-ContextPath";
private static final Logger logger = Logger.getLogger(
"com.sap.core.service.accessor.persistence.classloading.hook.AppLoaderClasspathExtenderClassLoadingHook");
private static final String PERSISTENCE_INTEGRATION_JAR_PROP_NAME = "persistence.integration.jar.name";
private static final String PERSISTENCE_INTEGRATION_JAR = System.getProperty(PERSISTENCE_INTEGRATION_JAR_PROP_NAME);
private static final String CONFIG_AREA = "osgi.configuration.area";
private static final String LIB_DIR = "lib";
private static final String PERSISTENCE_DIR = "persistence";
@Override
public void addHooks(HookRegistry registry) {
registry.addClassLoaderHook(this);
}
@Override
public boolean addClassPathEntry(ArrayList<ClasspathEntry> cpEntries, String cp, ClasspathManager hostmanager, Generation sourceGeneration) {
if (isAppBundle(sourceGeneration) && (shouldAdd(cpEntries))) {
ClasspathEntry persistenceIntegrationClasspathEntry = null;
try {
persistenceIntegrationClasspathEntry = determinePersistenceIntegrationPath(hostmanager, sourceGeneration);
} catch (ClasspathExtenderClassLoadingHookException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
}
if (persistenceIntegrationClasspathEntry != null) {
cpEntries.add(persistenceIntegrationClasspathEntry);
return true;
}
}
return false;
}
boolean shouldAdd(ArrayList<ClasspathEntry> cpEntries) {
for (ClasspathEntry cpEntry : cpEntries) {
if (cpEntry.getBundleFile().getBaseFile().getName().startsWith(PERSISTENCE_INTEGRATION_JAR)) {
return false;
}
}
return true;
}
ClasspathEntry determinePersistenceIntegrationPath(ClasspathManager hostmanager, Generation sourcedata)
throws ClasspathExtenderClassLoadingHookException {
if (persistenceIntegrationJar == null) {
findPersistenceIntegrationJar();
}
ClasspathEntry cp = hostmanager.getExternalClassPath(persistenceIntegrationJar.getAbsolutePath(), sourcedata);
if (cp == null) {
throw new ClasspathExtenderClassLoadingHookException("Failed to create classpath entry for file [" + PERSISTENCE_INTEGRATION_JAR + "]");
}
return cp;
}
void findPersistenceIntegrationJar() throws ClasspathExtenderClassLoadingHookException {
String configurationPath = System.getProperty(CONFIG_AREA);
if (configurationPath == null) {
throw new ClasspathExtenderClassLoadingHookException("Property [" + CONFIG_AREA + "] is missing");
}
File configurationFile = new File(normalize(configurationPath));
File lib = new File(configurationFile.getParentFile(), LIB_DIR);
if (!lib.exists()) {
throw new ClasspathExtenderClassLoadingHookException("lib folder is missing");
}
File persistenceLibDir = new File(lib, PERSISTENCE_DIR);
if (!persistenceLibDir.exists()) {
throw new ClasspathExtenderClassLoadingHookException("lib/persistence folder is missing");
}
String[] libs = persistenceLibDir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.startsWith(PERSISTENCE_INTEGRATION_JAR)) {
return true;
}
return false;
}
});
if (libs.length == 0) {
throw new ClasspathExtenderClassLoadingHookException(
"No file with name starting with [" + PERSISTENCE_INTEGRATION_JAR + "] was found in lib/persistence folder");
}
if (libs.length > 1) {
logger.log(Level.SEVERE, "Found " + libs.length + " files with name starting with [" + PERSISTENCE_INTEGRATION_JAR
+ "] was found in lib/persistence folder (one expected); choosing [" + libs[0] + "]");
}
persistenceIntegrationJar = new File(persistenceLibDir, libs[0]);
}
String normalize(String filePath) {
if (filePath.startsWith(FILE_SCHEME)) {
return filePath.substring(FILE_SCHEME.length());
}
return filePath;
}
boolean isAppBundle(Generation sourcedata) {
// TODO - review this change
if (sourcedata.getHeaders().get(WEB_CONTEXTPATH_HEADER) != null) {
return true;
}
return false;
}
@Override
public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager classpathManager) {
return null;
}
}