//
// Licensed 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.
//

=== Creating Bundles

The examples provides different kind of bundles and services definition:

* https://github.com/apache/karaf/blob/master/examples/karaf-bundle-example/README.md
* https://github.com/apache/karaf/blob/master/examples/karaf-blueprint-example/README.md
* https://github.com/apache/karaf/blob/master/examples/karaf-scr-example/README.md

==== Add extended information to bundles

Karaf supports a OSGI-INF/bundle.info file in a bundle.
This file is an extended description of the bundle.
It supports ASCII character declarations (for adding color, formatting, etc) and some simple Wiki syntax.

Simply add a `src/main/resources/OSGI-INF/bundle.info` file containing, for instance:

----
== SYNOPSIS
    ${project.description}

== DESCRIPTION
    Long description of your bundle, including usage, etc.

==SEE ALSO
    [http://yourside\]
    [http://yourside/docs\]
----

You can display this extended information using:

----
root@karaf> bundles:info
----

==== Wiki Syntax

Karaf supports some simple wiki syntax in bundle info files:

----
==, ===, ... : Headings
* : Enumerations
[http://....] : links
----

=== Creating bundles for non OSGi third party dependencies

==== Dynamically wrapping jars

Karaf supports the wrap: protocol execution.

It allows for directly deploying third party dependencies, like Apache Commons Lang:

----
root@karaf> bundles:install wrap:mvn:commons-lang/commons-lang/2.4
----

The wrap protocol creates a bundle dynamically using the bnd. Configurations can be added in the wrap URL:

* from the shell

----
root@karaf> bundles:install 'wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&Bundle-Version=2.4'
----

* from features.xml

----
<bundle>wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&amp;Bundle-Version=2.4</bundle>
----

Important notice : Add as child of your feature definition, the reference to wrap feature

----
<feature prerequisite="true">wrap</feature>
----

Additional information about meaning of `prerequisite` attribute can be found in link:provisioning[Feature prerequisites] description.

For instance : 

----
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="app-2.0.0">
	<feature name="external-libs" version="2.0.0" description="External libs">
		<details>External dependencies</details>
		<feature prerequisite="true">wrap</feature>
		<bundle start-level="80">wrap:mvn:net.sf.ehcache/ehcache-core/2.6.11$Bundle-SymbolicName=ehcache-core&amp;Bundle-Version=2.6.11</bundle>		
	</feature>
</features>
----

==== Statically bundling jars

You can also create a wrap bundle for a third party dependency.
This bundle is simply a Maven POM that shades an existing jar and package into a jar bundle.

For instance, to create an OSGi bundle that wraps Apache Commons Lang, simply define the following Maven POM:

----
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>osgi.commons-lang</groupId>
    <artifactId>osgi.commons-lang</artifactId>
    <version>2.4</version>
    <packaging>bundle</packaging>
    <name>commons-lang OSGi Bundle</name>
    <description>This OSGi bundle simply wraps commons-lang-2.4.jar artifact.</description>

    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.4</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>install</defaultGoal>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                            <includes>
                                <include>commons-lang:commons-lang</include>
                            </includes>
                        </artifactSet>
                        <filters>
                            <filter>
                                <artifact>commons-lang:commons-lang</artifact>
                                <excludes>
                                    <exclude>**</exclude>
                                </excludes>
                            </filter>
                        </filters>
                        <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>2.1.0</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                    <Export-Package></Export-Package>
                    <Import-Package></Import-Package>
                    <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
                    <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Embed-Dependency</_removeheaders>
                </instructions>
                <unpackBundle>true</unpackBundle>
            </configuration>
        </plugin>
    </build>

</project>
----

The resulting OSGi bundle can now be deployed directly:

----
root@karaf> bundles:install -s mvn:osgi.commons-lang/osgi.commons-lang/2.4
----
