/* | |
// * 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 WARRANTIESOR 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.aries.jpa.eclipselink.adapter; | |
import java.io.ByteArrayOutputStream; | |
import java.io.Closeable; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.Map; | |
import org.osgi.framework.Bundle; | |
import org.osgi.framework.BundleReference; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
public final class UnionClassLoader extends ClassLoader implements BundleReference { | |
private static final String ORG_OSGI_FRAMEWORK = "org.osgi.framework."; | |
private static final int DOT_INDEX = ORG_OSGI_FRAMEWORK.lastIndexOf('.'); | |
private static final Logger LOG = LoggerFactory.getLogger(UnionClassLoader.class); | |
private final Bundle eclipseLinkBundle; | |
private final Bundle adaptorBundle; | |
private final Map<String, Class<?>> registeredPlugins = new HashMap<String, Class<?>>(); | |
public UnionClassLoader(ClassLoader parentLoader, Bundle b, Bundle adaptor, Map<String, Object> arg1) { | |
super(parentLoader); | |
this.eclipseLinkBundle = b; | |
this.adaptorBundle = adaptor; | |
//Populate the plugins | |
Object o = arg1 == null ? null : arg1.get("org.apache.aries.jpa.eclipselink.plugin.types"); | |
if(o instanceof Class) { | |
Class<?> c = (Class<?>) o; | |
registeredPlugins.put(c.getName(), c); | |
} else if (o instanceof Collection) { | |
for(Object o2 : (Collection<?>) o) { | |
Class<?> c = (Class<?>) o2; | |
registeredPlugins.put(c.getName(), c); | |
} | |
} | |
} | |
@Override | |
protected Class<?> findClass(String name) throws ClassNotFoundException { | |
if(registeredPlugins.containsKey(name)) { | |
return registeredPlugins.get(name); | |
} | |
if ("org.apache.aries.jpa.eclipselink.adapter.platform.OSGiTSServer".equals(name) | |
|| "org.apache.aries.jpa.eclipselink.adapter.platform.OSGiTSWrapper".equals(name)) { | |
return loadTempClass(name); | |
} else if (name.startsWith(ORG_OSGI_FRAMEWORK) && name.lastIndexOf('.') == DOT_INDEX) { | |
return adaptorBundle.loadClass(name); | |
} | |
return eclipseLinkBundle.loadClass(name); | |
} | |
private Class<?> loadTempClass(String name) throws ClassNotFoundException, ClassFormatError { | |
InputStream is = getClass().getClassLoader().getResourceAsStream(name.replace('.', '/') + ".class"); | |
if (is == null) { | |
throw new ClassNotFoundException(name); | |
} | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
try { | |
copy(is, baos); | |
} catch (IOException ioe) { | |
throw new ClassNotFoundException(name, ioe); | |
} | |
return defineClass(name, baos.toByteArray(), 0, baos.size()); | |
} | |
@Override | |
public Bundle getBundle() { | |
return adaptorBundle; | |
} | |
private static void copy(InputStream in, OutputStream out) throws IOException { | |
try { | |
int len; | |
byte[] b = new byte[1024]; | |
while ((len = in.read(b)) != -1) { | |
out.write(b, 0, len); | |
} | |
} finally { | |
close(in); | |
} | |
} | |
private static void close(Closeable c) { | |
try { | |
if (c != null) { | |
c.close(); | |
} | |
} catch (IOException e) { | |
LOG.debug("Exception closing", e); | |
} | |
} | |
} |