BundleManager가 할 일
- 특정 폴더에 jar 파일을 집어 넣으면 그 녀석을 설치해야 한다.
- 이미 해당 jar 파일이 설치되어 있다면 설치하지 않는다.

BundleDirectoryManager.java

package whiteship;

import java.io.File;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

public class BundleDirectoryManager implements BundleActivator {

    private static final long INTERBAL = 1000;
    private static String BUNDLE_DIRECTORY = "E:\\bundles";
    private volatile BundleContext context;

    private final Thread thread = new BundleManager(BUNDLE_DIRECTORY);

    public void start(BundleContext context) throws Exception {
        this.context = context;
        thread.start();
    }

    public void stop(BundleContext context) throws Exception {
        thread.interrupt();
    }

    protected Bundle findBundleByLocation(String location) {
        Bundle[] bundles = context.getBundles();
        for (int i = 0; i < bundles.length; i++) {
            if (bundles[i].getLocation().equals(location)) {
                return bundles[i];
            }
        }
        return null;
    }

    private class BundleManager extends Thread {

        private File bundleLocation;

        public BundleManager() {
            //TODO I need CoC
        }

        public BundleManager(String location) {
            bundleLocation = new File(location);
        }

        public void run() {
            if (!bundleLocation.isDirectory())
                throw new RuntimeException(bundleLocation.getPath()
                        + " is not directory.");

            try {
                while (!Thread.currentThread().isInterrupted()) {
                    Thread.sleep(INTERBAL);

                    for (File file : bundleLocation.listFiles(new JarFileFilter())) {
                        String bundleLocation = "file:" + file.getAbsolutePath();
                        if(findBundleByLocation(bundleLocation) == null)
                            context.installBundle(bundleLocation);
                    }
                }
            } catch (InterruptedException e) {
                System.out.println("I'm going out");
            } catch (BundleException e) {
                System.out.println("Error installing bundle");
                throw new RuntimeException(e);
            }
        }

    }
}

번들을 시작시키면 위의 클래스에 있는 start()가 실행되고, 주기적으로(현재 1초) 특정 폴더(현재 E:\bundles)를 확인해서 그 안에 들어있는 JAR 파일들을 찾아서 설치한다. 이 때 만약 이미 OSGi 플랫폼에 설치되어 있는 번들은 설치하지 않는다.

JarFileFilter.java

package whiteship;

import java.io.File;
import java.io.FileFilter;

public class JarFileFilter implements FileFilter {

    public boolean accept(File f) {
        if(f.isDirectory())
            return false;
       
        String extenstion = getExtension(f);
        if(extenstion != null && extenstion.equals("jar"))
            return true;
       
        return false;
    }

     public String getExtension(File f) {
            String ext = null;
            String s = f.getName();
            int i = s.lastIndexOf('.');

            if (i > 0 &&  i < s.length() - 1) {
                ext = s.substring(i+1).toLowerCase();
            }
            return ext;
        }

}

파일 필터로. 특정 폴더 안에 들어있는 파일들 중에 확장자가 jar 인 파일들만 가져오기 위해서 만들었음.

bnd파일

# bundleManager.bnd
Private-Package: whiteship
Bundle-Activator: whiteship.BundleDirectoryManager

hk23.jar

개선하거나 생각해볼 것
- 스프링 DM 번들로 변경하자.
- 시간이랑 폴더는 DI가 가능하도록 변경하자.(기본 값 유지)
- jar 뿐만 아니라 war로 설치를 시도하게 하자. 스프링 DM 웹 번들일 수도 있으니까.
- getExtension() 메소드는 별도의 Util 클래스로 빼내기.
- 예외처리 RuntimeException으로 처리하기.

0.2
- 해당 폴더에서 jar 파일이 삭제되면, 해당 번들을 uninstall 시킨다.

0.3
- 만약 해당 폴더에 있는 jar 파일이 변경되면, 해당 번들을 update 시킨다.

참조: http://neilbartlett.name/blog/osgibook/