/*
 * 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.
 */
The Activator you will find in this example registers a ComponentExecutorFactory in the OSGi service
registry to enable parallel activation of (some or all) components 

DM uses a whiteboard pattern approach in order to handle components concurrently: your application has to register a ComponentExecutorFactory in 
the registry and DM will use it when deciding if components must be started concurrently (or not). By implementing yourself a ComponentExecutorFactory, 
you are allowed to first decide if a given component should be started concurrently, and also choose the threadpool you like, 
possibly a standard jdk threadpool, or some other advanced queuing libraries, like "hawtdispatch" ...

The ComponentExecutorFactory has a single method:

    /**
     * Returns an Executor used to handle and start the given component, or null if the component must be started synchronously.
     */
    public Executor getExecutorFor(Component component) {
    }
    
To indicate that DM should "wait for" a ComponentExecutorFactory before starting to handle any components, then you have to declare 
in the bundle context properties the following parameter:

    org.apache.felix.dependencymanager.parallelism=*

Using the above property will ensure that DM cache any added DM components until ComponentExecutorFactory is available from the OSGi registry.
Hence, using the above property avoids you to use start level service in order to make sure all components are started concurrently, even if the
bundle containing your ComponentExecutorFactory service is started lastly.

Finally, if you want to start all components in parallel, except some; then you can specify the list of packages to be excluded like this:

    org.apache.felix.dependencymanager.parallelism=!package.to.exclude,*

Here, components having a package that is starting with "package.to.exclude" won't be started concurrently.

Now, let's describe the example: it registers a ComponentExecutorFactory that only makes concurrent components 
which provide a "parallel=true" service property (you can specify a service property even if the component does not register any services).
Since we define ComponentExecutorFactory using DM API, we also have to disable parallelism for it, by declaring its package in the following parameter from 
the bundle context properties:

   org.apache.felix.dependencymanager.parallelism=!org.apache.felix.dependencymanager.samples.tpool.executor,*
   
To start the example, click on "tpool.bndrun" descriptor and run it.
You will then see:

Starting Component Component 1 current thread=Thread[main,5,main]
Starting Component Component 2 current thread=Thread[main,5,main]
Starting Component Parallel Component 3 current thread=Thread[pool-3-thread-1,5,main]
Starting Component Parallel Component 4 current thread=Thread[pool-3-thread-2,5,main]

Here, the Component 3 and 4 are started in the threadpool, while the Component 2 is started synchronously from the main thread.