Package org.apache.felix.connect

Source Code of org.apache.felix.connect.PojoSR

/*
* 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.apache.felix.connect;

import java.io.File;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.Version;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
import org.osgi.service.startlevel.StartLevel;

import org.apache.felix.connect.felix.framework.ServiceRegistry;
import org.apache.felix.connect.felix.framework.util.EventDispatcher;
import org.apache.felix.connect.launch.BundleDescriptor;
import org.apache.felix.connect.launch.ClasspathScanner;
import org.apache.felix.connect.launch.PojoServiceRegistry;
import org.apache.felix.connect.launch.PojoServiceRegistryFactory;

public class PojoSR implements PojoServiceRegistry
{
    private final BundleContext m_context;
    private final ServiceRegistry m_reg = new ServiceRegistry(
            new ServiceRegistry.ServiceRegistryCallbacks()
            {

                public void serviceChanged(ServiceEvent event,
                        Dictionary oldProps)
                {
                    m_dispatcher.fireServiceEvent(event, oldProps, null);
                }
            });

    private final EventDispatcher m_dispatcher = new EventDispatcher(m_reg);
    private final Map<Long, Bundle> m_bundles =new HashMap<Long, Bundle>();
    private final Map<String, Bundle> m_symbolicNameToBundle = new HashMap<String, Bundle>();
    private final Map bundleConfig;
    public PojoSR(Map config) throws Exception
    {
        final Map<String, String> headers = new HashMap<String, String>();
        headers.put(Constants.BUNDLE_SYMBOLICNAME,
                "org.apache.felix.connect");
        headers.put(Constants.BUNDLE_VERSION, "0.1.0-SNAPSHOT");
        headers.put(Constants.BUNDLE_NAME, "System Bundle");
        headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
    headers.put(Constants.BUNDLE_VENDOR, "Apache Software Foundation");
        bundleConfig = new HashMap(config);
        final Bundle b = new PojoSRBundle(new Revision()
        {

            @Override
            public long getLastModified()
            {
                // TODO Auto-generated method stub
                return System.currentTimeMillis();
            }

            @Override
            public Enumeration getEntries()
            {
                return new Properties().elements();
            }

            @Override
            public URL getEntry(String entryName)
            {
                return getClass().getClassLoader().getResource(entryName);
            }
        }, headers, new Version(0, 0, 1), "file:pojosr", m_reg, m_dispatcher,
                null, 0, "org.apache.felix.connect", m_bundles, getClass()
                        .getClassLoader(), bundleConfig)
        {
          @Override
          public synchronized void start() throws BundleException {
            if (m_state != Bundle.RESOLVED) {
              return;
            }
            m_dispatcher.startDispatching();
            m_state = Bundle.STARTING;

                m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTING,
                        this));
                m_context = new PojoSRBundleContext(this, m_reg, m_dispatcher,
                                m_bundles, bundleConfig);
                int i = 0;
                for (Bundle b : m_bundles.values()) {
                  i++;
                  try
                    {
                        if (b != this)
                        {
                            b.start();
                        }
                    }
                    catch (Throwable t)
                    {
                      System.out.println("Unable to start bundle: " + i );
                      t.printStackTrace();
                    }
                }
                m_state = Bundle.ACTIVE;
                m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STARTED,
                        this));

                m_dispatcher.fireFrameworkEvent(new FrameworkEvent(FrameworkEvent.STARTED, this, null));
            super.start();
          };
            @Override
            public synchronized void stop() throws BundleException
            {
              if ((m_state == Bundle.STOPPING) || m_state == Bundle.RESOLVED) {
                return;

              }
              else if (m_state != Bundle.ACTIVE) {
                throw new BundleException("Can't stop pojosr because it is not ACTIVE");
              }
              final Bundle systemBundle = this;
              Runnable r = new Runnable() {

          public void run() {
                    m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPING,
                        systemBundle));
                    for (Bundle b : m_bundles.values())
                    {
                        try
                        {
                            if (b != systemBundle)
                            {
                                b.stop();
                            }
                        }
                        catch (Throwable t)
                        {
                            t.printStackTrace();
                        }
                    }
                    m_dispatcher.fireBundleEvent(new BundleEvent(BundleEvent.STOPPED,
                        systemBundle));
                    m_state = Bundle.RESOLVED;
                    m_dispatcher.stopDispatching();
          }
        };
        m_state = Bundle.STOPPING;
        if ("true".equalsIgnoreCase(System.getProperty("org.apache.felix.connect.events.sync"))) {
          r.run();
        }
        else {
          new Thread(r).start();
        }
            }
        };
        m_symbolicNameToBundle.put(b.getSymbolicName(), b);
        b.start();
        b.getBundleContext().registerService(StartLevel.class.getName(),
                new StartLevel()
                {

                    public void setStartLevel(int startlevel)
                    {
                        // TODO Auto-generated method stub

                    }

                    public void setInitialBundleStartLevel(int startlevel)
                    {
                        // TODO Auto-generated method stub

                    }

                    public void setBundleStartLevel(Bundle bundle,
                            int startlevel)
                    {
                        // TODO Auto-generated method stub

                    }

                    public boolean isBundlePersistentlyStarted(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return true;
                    }

                    public boolean isBundleActivationPolicyUsed(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return false;
                    }

                    public int getStartLevel()
                    {
                        // TODO Auto-generated method stub
                        return 1;
                    }

                    public int getInitialBundleStartLevel()
                    {
                        // TODO Auto-generated method stub
                        return 1;
                    }

                    public int getBundleStartLevel(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return 1;
                    }
                }, null);

        b.getBundleContext().registerService(PackageAdmin.class.getName(),
                new PackageAdmin()
                {

                    public boolean resolveBundles(Bundle[] bundles)
                    {
                        // TODO Auto-generated method stub
                        return true;
                    }

                    public void refreshPackages(Bundle[] bundles)
                    {
                        m_dispatcher.fireFrameworkEvent(new FrameworkEvent(
                                FrameworkEvent.PACKAGES_REFRESHED, b, null));
                    }

                    public RequiredBundle[] getRequiredBundles(
                            String symbolicName)
                    {
                        return null;
                    }

                    public Bundle[] getHosts(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public Bundle[] getFragments(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public ExportedPackage[] getExportedPackages(String name)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public ExportedPackage[] getExportedPackages(Bundle bundle)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public ExportedPackage getExportedPackage(String name)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public Bundle[] getBundles(String symbolicName,
                            String versionRange)
                    {
              Bundle result = m_symbolicNameToBundle.get((symbolicName != null) ? symbolicName.trim() : symbolicName);
            if (result != null) {
              return new Bundle[] {result};
            }
            return null;
                    }

                    public int getBundleType(Bundle bundle)
                    {
                        return 0;
                    }

                    public Bundle getBundle(Class clazz)
                    {
                        return m_context.getBundle();
                    }
                }, null);
        m_context = b.getBundleContext();

        List<BundleDescriptor> scan = (List<BundleDescriptor>) config
                .get(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS);

        if (scan != null)
        {
            startBundles(scan);
    }
    }

  public void startBundles(List<BundleDescriptor> scan) throws Exception {
   for (BundleDescriptor desc : scan)
            {
                URL u = new URL(desc.getUrl().toExternalForm()
                        + "META-INF/MANIFEST.MF");
                Revision r;
                if (u.toExternalForm().startsWith("file:"))
                {
                    File root = new File(URLDecoder.decode(desc.getUrl()
                            .getFile(), "UTF-8"));
                    u = root.toURL();
                    r = new DirRevision(root);
                }
                else
                {
                    URLConnection uc = u.openConnection();
                    if (uc instanceof JarURLConnection)
                    {
              String target = ((JarURLConnection) uc).getJarFileURL().toExternalForm();
            String prefix = null;
            if (!("jar:" + target + "!/").equals(desc.getUrl().toExternalForm())) {
                prefix = desc.getUrl().toExternalForm().substring(("jar:" + target + "!/").length());
            }
                        r = new JarRevision(
                                ((JarURLConnection) uc).getJarFile(),
                                ((JarURLConnection) uc).getJarFileURL(),
                prefix,
                                uc.getLastModified());
                    }
                    else
                    {
                        r = new URLRevision(desc.getUrl(), desc.getUrl()
                                .openConnection().getLastModified());
                    }
                }
                Map<String, String> bundleHeaders = desc.getHeaders();
        Version osgiVersion = null;
        try {
          osgiVersion = Version.parseVersion(bundleHeaders.get(Constants.BUNDLE_VERSION));
        } catch (Exception ex) {
          ex.printStackTrace();
          osgiVersion = Version.emptyVersion;
        }
                String sym = bundleHeaders.get(Constants.BUNDLE_SYMBOLICNAME);
                    if (sym != null)
                    {
                        int idx = sym.indexOf(';');
                        if (idx > 0)
                        {
                            sym = sym.substring(0, idx);
                        }
            sym = sym.trim();
                    }

                if ((sym == null)
                        || !m_symbolicNameToBundle.containsKey( sym ))
                {
                    // TODO: framework - support multiple versions
                    Bundle bundle = new PojoSRBundle(r, bundleHeaders,
                            osgiVersion, desc.getUrl().toExternalForm(), m_reg,
                            m_dispatcher,
                            bundleHeaders.get(Constants.BUNDLE_ACTIVATOR),
                            m_bundles.size(),
                            sym,
                            m_bundles, desc.getClassLoader(), bundleConfig);
                    if (sym != null)
                    {
                        m_symbolicNameToBundle.put(bundle.getSymbolicName(),
                                bundle);
                    }
                }

            }


        for (long i = 1; i < m_bundles.size(); i++)
        {
            try
            {
                m_bundles.get(i).start();
            }
            catch (Throwable e)
            {
                System.out.println("Unable to start bundle: " + i);
                e.printStackTrace();
            }
        }

  }

    public static void main(String[] args) throws Exception
    {
      Filter filter = null;
      Class main = null;
      for (int i = 0;(args != null) && (i < args.length) && (i < 2); i++) {
        try {
          filter = FrameworkUtil.createFilter(args[i]);
        } catch (InvalidSyntaxException ie) {
          try {
            main = PojoSR.class.getClassLoader().loadClass(args[i]);
          } catch (Exception ex) {
            throw new IllegalArgumentException("Argument is neither a filter nor a class: " + args[i]);
          }
        }
      }
        Map config = new HashMap();
        config.put(
                PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS,
                (filter != null) ? new ClasspathScanner()
                        .scanForBundles(filter.toString()) : new ClasspathScanner()
                        .scanForBundles());
        new PojoServiceRegistryFactoryImpl().newPojoServiceRegistry(config);
        if (main != null) {
          int count = 0;
          if (filter != null) {
            count++;
          }
          if (main != null) {
            count++;
          }
          String[] newArgs = args;
          if (count > 0) {
            newArgs = new String[args.length - count];
            System.arraycopy(args, count, newArgs, 0, newArgs.length);
          }
          main.getMethod("main", String[].class).invoke(null, (Object) newArgs );
        }
    }

    public BundleContext getBundleContext()
    {
        return m_context;
    }

    public void addServiceListener(ServiceListener listener, String filter)
            throws InvalidSyntaxException
    {
        m_context.addServiceListener(listener, filter);
    }

    public void addServiceListener(ServiceListener listener)
    {
        m_context.addServiceListener(listener);
    }

    public void removeServiceListener(ServiceListener listener)
    {
        m_context.removeServiceListener(listener);
    }

    public ServiceRegistration registerService(String[] clazzes,
            Object service, Dictionary properties)
    {
        return m_context.registerService(clazzes, service, properties);
    }

    public ServiceRegistration registerService(String clazz, Object service,
            Dictionary properties)
    {
        return m_context.registerService(clazz, service, properties);
    }

    public ServiceReference[] getServiceReferences(String clazz, String filter)
            throws InvalidSyntaxException
    {
        return m_context.getServiceReferences(clazz, filter);
    }

    public ServiceReference getServiceReference(String clazz)
    {
        return m_context.getServiceReference(clazz);
    }

    public Object getService(ServiceReference reference)
    {
        return m_context.getService(reference);
    }

    public boolean ungetService(ServiceReference reference)
    {
        return m_context.ungetService(reference);
    }
}
TOP

Related Classes of org.apache.felix.connect.PojoSR

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.