package com.github.dynamicextensionsalfresco.proxy;

import com.github.dynamicextensionsalfresco.osgi.FrameworkService;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.felix.framework.FilterImpl;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.springframework.beans.factory.FactoryBean;

/**
 * Spring [FactoryBean] to allow registration of service proxies at the global Alfresco level.
 * The emitted proxy will delegate to a service implemented by a Dynamic Extension, if any.
 *
 * These proxies are not guaranteed to be available at all times (startup or bundle uninstall),
 * so users of these proxies should handle [IllegalStateException] explicitly.
 *
 * The [Filter] will select the appropriate target instance for the proxy.
 * If you do not define it explicitly, the targetInterfaces will be used to compose one.
 * (find a extension service, implementing all specified interfaces.
 *
 * Note, that the filter should be specific enough to limit any matches to 1 service: if more then 1 match is found,
 * an [IllegalStateException] will be throw.
 */
public class BundleServiceProxyFactory<T> implements FactoryBean<T> {

    private List<Class<?>> targetInterfaces = new ArrayList<Class<?>>();
    public void setTargetInterfaces(List<Class<?>> targetInterfaces) {
        this.targetInterfaces = targetInterfaces;
    }

    private FrameworkService frameworkService = null;
    public void setFrameworkService(FrameworkService frameworkService) {
        this.frameworkService = frameworkService;
    }

    private Filter filter = null;
    public void setFilterString(String filterString) throws InvalidSyntaxException {
        this.filter = new FilterImpl(filterString);
    }

    @Override
    public boolean isSingleton() { return true; }

    @Override
    @SuppressWarnings("unchecked")
    public T getObject() {
        Tracker tracker = new Tracker(new DefaultFilterModel(targetInterfaces, filter), frameworkService);
        Class<?>[] proxyClasses = targetInterfaces.toArray(new Class<?>[targetInterfaces.size() + 1]);
        proxyClasses[targetInterfaces.size()] = FilterModel.class;

        return (T)Proxy.newProxyInstance(
                this.getClass().getClassLoader(),
                proxyClasses,
                new ServiceInvocationHandler(tracker));
    }

    @Override
    public Class<?> getObjectType() {
        if (targetInterfaces == null || targetInterfaces.size() == 0) {
            return null;
        } else {
            return targetInterfaces.get(0);
        }
    }
}

@@ -420,17 +420,23 @@
  Spring 
-%5B
+%7B@link 
 FactoryB
@@ -438,17 +438,17 @@
 toryBean
-%5D
+%7D
  to allo
@@ -745,17 +745,23 @@
  handle 
-%5B
+%7B@link 
 IllegalS
@@ -773,17 +773,17 @@
 xception
-%5D
+%7D
  explici
@@ -801,16 +801,22 @@
 The 
-%5B
+%7B@link 
 Filter
-%5D
+%7D
  wil
@@ -1155,17 +1155,23 @@
 ,%0A * an 
-%5B
+%7B@link 
 IllegalS
@@ -1183,17 +1183,17 @@
 xception
-%5D
+%7D
  will be

Use correct JavaDoc links