org.netbeans.modules.netbinox.NetbinoxHooks Maven / Gradle / Ivy
The newest version!
/*
* 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.netbeans.modules.netbinox;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.net.URLConnection;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.eclipse.osgi.baseadaptor.BaseAdaptor;
import org.eclipse.osgi.baseadaptor.BaseData;
import org.eclipse.osgi.baseadaptor.HookConfigurator;
import org.eclipse.osgi.baseadaptor.HookRegistry;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
import org.eclipse.osgi.baseadaptor.bundlefile.MRUBundleFileList;
import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
import org.eclipse.osgi.baseadaptor.hooks.BundleFileFactoryHook;
import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.netbeans.core.netigso.spi.NetigsoArchive;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.wiring.BundleWiring;
/**
*
* @author Jaroslav Tulach
*/
public final class NetbinoxHooks implements HookConfigurator, ClassLoadingHook,
BundleFileFactoryHook, FrameworkLog, FrameworkListener, AdaptorHook, LookupListener {
private static Map map;
private static NetigsoArchive archive;
private static Lookup.Result configurators;
private static Collection extends HookConfigurator> previous = Collections.emptyList();
private static HookRegistry hookRegistry;
@Override
public void addHooks(HookRegistry hr) {
initRegistry(hr, this);
initAndRefresh();
}
@Override
public byte[] processClass(String className, byte[] bytes, ClasspathEntry ce, BundleEntry be, ClasspathManager cm) {
final BaseData bd = ce.getBaseData();
if (bd == null) {
return bytes;
}
final Bundle b = bd.getBundle();
if (b == null) {
return bytes;
}
BundleWiring w = b.adapt(org.osgi.framework.wiring.BundleWiring.class);
if (w == null) {
return bytes;
}
ClassLoader loader = w.getClassLoader();
return archive.patchByteCode(loader, className, ce.getDomain(), bytes);
}
@Override
public boolean addClassPathEntry(ArrayList al, String string, ClasspathManager cm, BaseData bd, ProtectionDomain pd) {
return false;
}
@Override
public String findLibrary(BaseData bd, String string) {
return null;
}
@Override
public ClassLoader getBundleClassLoaderParent() {
return null;
}
@Override
public BaseClassLoader createClassLoader(ClassLoader parent, final ClassLoaderDelegate delegate, final BundleProtectionDomain bpd, BaseData bd, String[] classpath) {
String loc = bd.getBundle().getLocation();
//NetigsoModule.LOG.log(Level.FINER, "createClassLoader {0}", bd.getLocation());
final String pref = "netigso://"; // NOI18N
ClassLoader ml = null;
if (loc != null && loc.startsWith(pref)) {
ml = classLoaderForBundle(bd);
}
if (ml == null) {
return new NetbinoxLoader(parent, delegate, bpd, bd, classpath);
} else {
return new NetigsoBaseLoader(ml, delegate, bpd, bd);
}
}
@Override
public void initializedClassLoader(BaseClassLoader bcl, BaseData bd) {
}
private final MRUBundleFileList mruList = new MRUBundleFileList();
@Override
public BundleFile createBundleFile(Object file, final BaseData bd, boolean isBase) throws IOException {
if (file instanceof File) {
final File f = (File)file;
// running with fake manifest fails for some reason, disabling for now
// final String loc = bd.getLocation();
// if (loc != null && loc.startsWith("netigso://")) {
// return new NetigsoBundleFile(f, bd);
// }
return new JarBundleFile(f, bd, archive, mruList, isBase);
}
return null;
}
@Override
public void frameworkEvent(FrameworkEvent ev) {
if (ev.getType() == FrameworkEvent.ERROR) {
log(ev);
}
}
@Override
public void log(FrameworkEvent fe) {
Level l = Level.FINE;
if ((fe.getType() & FrameworkEvent.ERROR) != 0) {
l = Level.SEVERE;
} else if ((fe.getType() & FrameworkEvent.WARNING) != 0) {
l = Level.WARNING;
} else if ((fe.getType() & FrameworkEvent.INFO) != 0) {
l = Level.INFO;
}
LogRecord lr = new LogRecord(l, "framework event {0} type {1}");
lr.setParameters(new Object[]{fe.getBundle().getSymbolicName(), fe.getType()});
lr.setThrown(fe.getThrowable());
lr.setLoggerName(NetbinoxFactory.LOG.getName());
NetbinoxFactory.LOG.log(lr);
}
@Override
public void log(FrameworkLogEntry fle) {
NetbinoxFactory.LOG.log(Level.FINE, "entry {0}", fle);
}
@Override
public void setWriter(Writer writer, boolean bln) {
}
@Override
public void setFile(File file, boolean bln) throws IOException {
}
@Override
public File getFile() {
return null;
}
@Override
public void setConsoleLog(boolean bln) {
}
@Override
public void close() {
}
// adaptor hooks
@Override
public void initialize(BaseAdaptor ba) {
}
@Override
public void frameworkStart(BundleContext bc) throws BundleException {
bc.addFrameworkListener(this);
}
@Override
public void frameworkStop(BundleContext bc) throws BundleException {
bc.removeFrameworkListener(this);
}
@Override
public void frameworkStopping(BundleContext bc) {
}
@Override
public void addProperties(Properties prprts) {
}
@Override
public URLConnection mapLocationToURLConnection(String string) throws IOException {
return null;
}
@Override
public void handleRuntimeError(Throwable thrwbl) {
NetbinoxFactory.LOG.log(Level.WARNING, thrwbl.getMessage(), thrwbl);
}
@Override
public FrameworkLog createFrameworkLog() {
return this;
}
@Override
public void resultChanged(LookupEvent ev) {
initAndRefresh();
}
//
// synchronized to access internal data structures
//
private void initAndRefresh() {
Set added;
synchronized (NetbinoxHooks.class) {
if (configurators == null) {
configurators = Lookup.getDefault().lookupResult(HookConfigurator.class);
configurators.addLookupListener(this);
}
Collection extends HookConfigurator> now = configurators.allInstances();
added = new HashSet(now);
added.removeAll(previous);
previous = now;
}
for (HookConfigurator hc : added) {
hc.addHooks(hookRegistry);
}
}
static synchronized void clear() {
map = null;
archive = null;
configurators = null;
hookRegistry = null;
}
private static synchronized ClassLoader classLoaderForBundle(BaseData bd) {
if (map == null) {
return null;
}
return map.get(bd.getBundle());
}
static synchronized void registerMap(Map bundleMap) {
map = bundleMap;
}
static synchronized void registerArchive(NetigsoArchive netigsoArchive) {
archive = netigsoArchive;
}
private static synchronized void initRegistry(HookRegistry hr, NetbinoxHooks hooks) {
hookRegistry = hr;
hr.addClassLoadingHook(hooks);
hr.addBundleFileFactoryHook(hooks);
hr.addAdaptorHook(hooks);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy