/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.launch.base.internal; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.apache.felix.framework.Felix; import org.osgi.framework.BundleException; import org.osgi.framework.launch.Framework; import org.solmix.launch.base.shared.Loader; import org.solmix.launch.base.shared.Notifiable; /** * * @author ffz * @version 0.0.1 2012-3-18 * @since 0.0.4 */ public class OsgiFrameworkFactoryImpl implements OsgiFrameworkFactory { /** * {@inheritDoc} * * @see org.solmix.launch.shared.internal.OsgiFrameworkFactory#newFramework(org.solmix.launch.shared.Notifiable, * java.util.Map) */ @Override public Framework newFramework(Notifiable notifiable, Properties configuration) { return new SolmixFelix(notifiable, configuration); } private class SolmixFelix extends Felix { private final Notifiable notifiable; private Thread notifierThread; /** * @param notifiable * @param configMap */ public SolmixFelix(final Notifiable notifiable, Properties configMap) { super(configMap); this.notifiable = notifiable; } @Override public void update() throws BundleException { update(null); } @Override public void update(final InputStream is) throws BundleException { // get the update file and make sure, the stream is closed try { startNotifier(true, is); } finally { if (is != null) { try { is.close(); } catch (IOException ignore) { } } } // just stop the framework now super.stop(); } // public void restart() throws BundleException { // super.stop(); // } @Override public void stop() throws BundleException { startNotifier(false, null); super.stop(); } public void stop(final int status) throws BundleException { startNotifier(false, null); super.stop(status); } private synchronized void startNotifier(final boolean restart, final InputStream ins) { if (notifierThread == null) { notifierThread = new Thread(new Notifier(restart, ins), "Solmix Servlet Notifier"); notifierThread.setDaemon(false); notifierThread.start(); } } private class Notifier implements Runnable { private final boolean restart; private final File updateFile; private Notifier(final boolean restart, final InputStream ins) { this.restart = restart; if (ins != null) { File tmpFile; try { tmpFile = File.createTempFile("tmpupdate", ".jar"); Loader.spool(ins, tmpFile); } catch (IOException ioe) { // TOOD: log tmpFile = null; } this.updateFile = tmpFile; } else { this.updateFile = null; } } public void run() { try { SolmixFelix.this.waitForStop(0); } catch (InterruptedException ie) { // TODO: log } if (restart) { SolmixFelix.this.notifiable.updated(updateFile); } else { SolmixFelix.this.notifiable.stopped(); } } } } }