Search in sources :

Example 1 with AdapterFactoryDescriptor

use of org.apache.sling.adapter.internal.AdapterFactoryDescriptor in project sling by apache.

the class MockAdapterManagerImpl method createAdapterFactoryMap.

/**
     * Creates a new target adapter factory map for the given <code>clazz</code>.
     * First all factories defined to support the adaptable class by
     * registration are taken. Next all factories for the implemented interfaces
     * and finally all base class factories are copied.
     *
     * @param clazz The adaptable <code>Class</code> for which to build the
     *            adapter factory map by target class name.
     * @return The map of adapter factories by target class name. The map may be
     *         empty if there is no adapter factory for the adaptable
     *         <code>clazz</code>.
     */
private Map<String, List<AdapterFactoryDescriptor>> createAdapterFactoryMap(final Class<?> clazz) {
    final Map<String, List<AdapterFactoryDescriptor>> afm = new HashMap<String, List<AdapterFactoryDescriptor>>();
    // AdapterFactories for this class
    AdapterFactoryDescriptorMap afdMap = null;
    synchronized (this.descriptors) {
        afdMap = this.descriptors.get(clazz.getName());
    }
    if (afdMap != null) {
        final List<AdapterFactoryDescriptor> afdSet;
        synchronized (afdMap) {
            afdSet = new ArrayList<AdapterFactoryDescriptor>(afdMap.values());
        }
        for (final AdapterFactoryDescriptor afd : afdSet) {
            final String[] adapters = afd.getAdapters();
            for (final String adapter : adapters) {
                // to handle service ranking, we add to the end of the list or create a new list
                List<AdapterFactoryDescriptor> factoryDescriptors = afm.get(adapter);
                if (factoryDescriptors == null) {
                    factoryDescriptors = new ArrayList<AdapterFactoryDescriptor>();
                    afm.put(adapter, factoryDescriptors);
                }
                factoryDescriptors.add(afd);
            }
        }
    }
    // AdapterFactories for the interfaces
    final Class<?>[] interfaces = clazz.getInterfaces();
    for (final Class<?> iFace : interfaces) {
        copyAdapterFactories(afm, iFace);
    }
    // AdapterFactories for the super class
    final Class<?> superClazz = clazz.getSuperclass();
    if (superClazz != null) {
        copyAdapterFactories(afm, superClazz);
    }
    return afm;
}
Also used : AdapterFactoryDescriptorMap(org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AdapterFactoryDescriptor(org.apache.sling.adapter.internal.AdapterFactoryDescriptor) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 2 with AdapterFactoryDescriptor

use of org.apache.sling.adapter.internal.AdapterFactoryDescriptor in project sling by apache.

the class MockAdapterManagerImpl method getAdapter.

// DISABLED IN THIS COPY OF CLASS
/*
    @Reference
    private PackageAdmin packageAdmin;
    */
// ---------- AdapterManager interface -------------------------------------
/**
     * Returns the adapted <code>adaptable</code> or <code>null</code> if
     * the object cannot be adapted.
     *
     * @see org.apache.sling.api.adapter.AdapterManager#getAdapter(java.lang.Object, java.lang.Class)
     */
public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) {
    // get the adapter factories for the type of adaptable object
    final Map<String, List<AdapterFactoryDescriptor>> factories = getAdapterFactories(adaptable.getClass());
    // get the factory for the target type
    final List<AdapterFactoryDescriptor> descList = factories.get(type.getName());
    if (descList != null && descList.size() > 0) {
        for (AdapterFactoryDescriptor desc : descList) {
            final AdapterFactory factory = desc == null ? null : desc.getFactory();
            // have the factory adapt the adaptable if the factory exists
            if (factory != null) {
                log.debug("Trying adapter factory {} to map {} to {}", new Object[] { factory, adaptable, type });
                AdapterType adaptedObject = factory.getAdapter(adaptable, type);
                if (adaptedObject != null) {
                    log.debug("Using adapter factory {} to map {} to {}", new Object[] { factory, adaptable, type });
                    return adaptedObject;
                }
            }
        }
    }
    // no factory has been found, so we cannot adapt
    log.debug("No adapter factory found to map {} to {}", adaptable, type);
    return null;
}
Also used : AdapterFactoryDescriptor(org.apache.sling.adapter.internal.AdapterFactoryDescriptor) AdapterFactory(org.apache.sling.api.adapter.AdapterFactory) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 3 with AdapterFactoryDescriptor

use of org.apache.sling.adapter.internal.AdapterFactoryDescriptor in project sling by apache.

the class MockAdapterManagerImpl method registerAdapterFactory.

/**
     * Unregisters the {@link AdapterFactory} referred to by the service
     * <code>reference</code> from the registry.
     */
private void registerAdapterFactory(final ComponentContext context, final ServiceReference reference) {
    final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES));
    final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES));
    if (adaptables == null || adaptables.length == 0 || adapters == null || adapters.length == 0) {
        return;
    }
    // DISABLED IN THIS COPY OF CLASS
    /*
        for (String clazz : adaptables) {
            if (!checkPackage(packageAdmin, clazz)) {
                log.warn("Adaptable class {} in factory service {} is not in an exported package.", clazz, reference.getProperty(Constants.SERVICE_ID));
            }
        }

        for (String clazz : adapters) {
            if (!checkPackage(packageAdmin, clazz)) {
                log.warn("Adapter class {} in factory service {} is not in an exported package.", clazz, reference.getProperty(Constants.SERVICE_ID));
            }
        }
        */
    final AdapterFactoryDescriptor factoryDesc = new AdapterFactoryDescriptor(context, reference, adapters);
    for (final String adaptable : adaptables) {
        AdapterFactoryDescriptorMap adfMap = null;
        synchronized (this.descriptors) {
            adfMap = descriptors.get(adaptable);
            if (adfMap == null) {
                adfMap = new AdapterFactoryDescriptorMap();
                descriptors.put(adaptable, adfMap);
            }
        }
        synchronized (adfMap) {
            adfMap.put(reference, factoryDesc);
        }
    }
    // clear the factory cache to force rebuild on next access
    this.factoryCache.clear();
    // register adaption
    final Dictionary<String, Object> props = new Hashtable<String, Object>();
    props.put(SlingConstants.PROPERTY_ADAPTABLE_CLASSES, adaptables);
    props.put(SlingConstants.PROPERTY_ADAPTER_CLASSES, adapters);
    ServiceRegistration adaptionRegistration = this.context.getBundleContext().registerService(Adaption.class.getName(), AdaptionImpl.INSTANCE, props);
    if (log.isDebugEnabled()) {
        log.debug("Registered service {} with {} : {} and {} : {}", new Object[] { Adaption.class.getName(), SlingConstants.PROPERTY_ADAPTABLE_CLASSES, Arrays.toString(adaptables), SlingConstants.PROPERTY_ADAPTER_CLASSES, Arrays.toString(adapters) });
    }
    factoryDesc.setAdaption(adaptionRegistration);
    // send event
    final EventAdmin localEA = this.eventAdmin;
    if (localEA != null) {
        localEA.postEvent(new Event(SlingConstants.TOPIC_ADAPTER_FACTORY_ADDED, props));
    }
}
Also used : AdapterFactoryDescriptorMap(org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap) Adaption(org.apache.sling.adapter.Adaption) EventAdmin(org.osgi.service.event.EventAdmin) AdapterFactoryDescriptor(org.apache.sling.adapter.internal.AdapterFactoryDescriptor) Hashtable(java.util.Hashtable) Event(org.osgi.service.event.Event) ServiceRegistration(org.osgi.framework.ServiceRegistration)

Example 4 with AdapterFactoryDescriptor

use of org.apache.sling.adapter.internal.AdapterFactoryDescriptor in project sling by apache.

the class MockAdapterManagerImpl method copyAdapterFactories.

/**
     * Copies all adapter factories for the given <code>clazz</code> from the
     * <code>cache</code> to the <code>dest</code> map except for those
     * factories whose target class already exists in the <code>dest</code>
     * map.
     *
     * @param dest The map of target class name to adapter factory into which
     *            additional factories are copied. Existing factories are not
     *            replaced.
     * @param clazz The adaptable class whose adapter factories are considered
     *            for adding into <code>dest</code>.
     */
private void copyAdapterFactories(final Map<String, List<AdapterFactoryDescriptor>> dest, final Class<?> clazz) {
    // get the adapter factories for the adaptable clazz
    final Map<String, List<AdapterFactoryDescriptor>> scMap = getAdapterFactories(clazz);
    // for each target class copy the entry to dest and put it in the list or create the list
    for (Map.Entry<String, List<AdapterFactoryDescriptor>> entry : scMap.entrySet()) {
        List<AdapterFactoryDescriptor> factoryDescriptors = dest.get(entry.getKey());
        if (factoryDescriptors == null) {
            factoryDescriptors = new ArrayList<AdapterFactoryDescriptor>();
            dest.put(entry.getKey(), factoryDescriptors);
        }
        for (AdapterFactoryDescriptor descriptor : entry.getValue()) {
            factoryDescriptors.add(descriptor);
        }
    }
}
Also used : AdapterFactoryDescriptor(org.apache.sling.adapter.internal.AdapterFactoryDescriptor) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AdapterFactoryDescriptorMap(org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap)

Example 5 with AdapterFactoryDescriptor

use of org.apache.sling.adapter.internal.AdapterFactoryDescriptor in project sling by apache.

the class MockAdapterManagerImpl method unregisterAdapterFactory.

/**
     * Check that the package containing the class is exported or is a java.*
     * class.
     * 
     * @param packageAdmin the PackageAdmin service
     * @param clazz the class name
     * @return true if the package is exported
     */
// DISABLED IN THIS COPY OF CLASS
/*
    static boolean checkPackage(PackageAdmin packageAdmin, String clazz) {
        final String packageName = getPackageName(clazz); 
        if (packageName.startsWith("java.")) {
            return true;
        }
        return packageAdmin.getExportedPackage(packageName) != null;
    }
    */
/**
     * Unregisters the {@link AdapterFactory} referred to by the service
     * <code>reference</code> from the registry.
     */
private void unregisterAdapterFactory(final ServiceReference reference) {
    synchronized (this.boundAdapterFactories) {
        boundAdapterFactories.remove(reference);
    }
    final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES));
    final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES));
    if (adaptables == null || adaptables.length == 0 || adapters == null || adapters.length == 0) {
        return;
    }
    boolean factoriesModified = false;
    AdapterFactoryDescriptorMap adfMap = null;
    AdapterFactoryDescriptor removedDescriptor = null;
    for (final String adaptable : adaptables) {
        synchronized (this.descriptors) {
            adfMap = this.descriptors.get(adaptable);
        }
        if (adfMap != null) {
            synchronized (adfMap) {
                AdapterFactoryDescriptor factoryDesc = adfMap.remove(reference);
                if (factoryDesc != null) {
                    factoriesModified = true;
                    // Since the code paths above does not fully guarantee it though, let's keep this check in place
                    if (removedDescriptor != null && removedDescriptor != factoryDesc) {
                        log.error("When unregistering reference {} got duplicate service descriptors {} and {}. Unregistration of {} services may be incomplete.", new Object[] { reference, removedDescriptor, factoryDesc, Adaption.class.getName() });
                    }
                    removedDescriptor = factoryDesc;
                }
            }
        }
    }
    // removed
    if (factoriesModified) {
        this.factoryCache.clear();
    }
    // unregister adaption
    if (removedDescriptor != null) {
        removedDescriptor.getAdaption().unregister();
        if (log.isDebugEnabled()) {
            log.debug("Unregistered service {} with {} : {} and {} : {}", new Object[] { Adaption.class.getName(), SlingConstants.PROPERTY_ADAPTABLE_CLASSES, Arrays.toString(adaptables), SlingConstants.PROPERTY_ADAPTER_CLASSES, Arrays.toString(adapters) });
        }
    }
    // send event
    final EventAdmin localEA = this.eventAdmin;
    if (localEA != null) {
        final Dictionary<String, Object> props = new Hashtable<String, Object>();
        props.put(SlingConstants.PROPERTY_ADAPTABLE_CLASSES, adaptables);
        props.put(SlingConstants.PROPERTY_ADAPTER_CLASSES, adapters);
        localEA.postEvent(new Event(SlingConstants.TOPIC_ADAPTER_FACTORY_REMOVED, props));
    }
}
Also used : AdapterFactoryDescriptorMap(org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap) Adaption(org.apache.sling.adapter.Adaption) EventAdmin(org.osgi.service.event.EventAdmin) AdapterFactoryDescriptor(org.apache.sling.adapter.internal.AdapterFactoryDescriptor) Hashtable(java.util.Hashtable) Event(org.osgi.service.event.Event)

Aggregations

AdapterFactoryDescriptor (org.apache.sling.adapter.internal.AdapterFactoryDescriptor)5 AdapterFactoryDescriptorMap (org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap)4 ArrayList (java.util.ArrayList)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 HashMap (java.util.HashMap)2 Hashtable (java.util.Hashtable)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Adaption (org.apache.sling.adapter.Adaption)2 Event (org.osgi.service.event.Event)2 EventAdmin (org.osgi.service.event.EventAdmin)2 Map (java.util.Map)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 AdapterFactory (org.apache.sling.api.adapter.AdapterFactory)1 ServiceRegistration (org.osgi.framework.ServiceRegistration)1