Package org.apache.cxf.dosgi.dsw

Source Code of org.apache.cxf.dosgi.dsw.OsgiUtils

/**
* 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.
*/
package org.apache.cxf.dosgi.dsw;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.cxf.dosgi.dsw.decorator.ServiceDecorator;
import org.apache.cxf.dosgi.dsw.qos.IntentMap;
import org.apache.cxf.dosgi.dsw.service.RemoteServiceAdminCore;
import org.apache.cxf.ws.policy.spring.PolicyNamespaceHandler;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.springframework.context.ApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;

public final class OsgiUtils {

    // TODO: cleanup old code fragments !!!
   
    private static final Logger LOG = Logger.getLogger(OsgiUtils.class.getName());

    private static final String REMOTE_SERVICES_HEADER_NAME = "Remote-Service";
    private static final String REMOTE_SERVICES_DIRECTORY = "OSGI-INF/remote-service";
    private static final String REMOTE_SERVICES_NS = "http://www.osgi.org/xmlns/sd/v1.0.0";

    static final String[] INTENT_MAP = {
        "/OSGI-INF/cxf/intents/intent-map.xml"
    };

    private static final String SERVICE_DESCRIPTION_ELEMENT = "service-description";

//    private static final String PROVIDE_INTERFACE_ELEMENT = "provide";
//    private static final String PROVIDE_INTERFACE_NAME_ATTRIBUTE = "interface";

//    private static final String PROPERTY_ELEMENT = "property";
//    private static final String PROPERTY_NAME_ATTRIBUTE = "name";
//    private static final String PROPERTY_VALUE_ATTRIBUTE = "value";
//    private static final String PROPERTY_INTERFACE_ATTRIBUTE = "interface";

//    private static final String INTERFACE_WILDCARD = "*";
//    private static final String INTERFACE_SEPARATOR = ":";

    private OsgiUtils() {
    }

//    // Used by PublishHook
//    public static ServiceEndpointDescription getRemoteReference(ServiceReference sref, boolean matchAllNames) {
//
//        String[] names = (String[])sref.getProperty(org.osgi.framework.Constants.OBJECTCLASS);
//        if (names == null || names.length == 0) {
//            return null;
//        }
//
//        Map<String, Object> userProperties = new HashMap<String, Object>();
//        for (String key : sref.getPropertyKeys()) {
//            userProperties.put(key, sref.getProperty(key));
//        }
//        List<ServiceEndpointDescription> srefs = getRemoteReferences(sref.getBundle(), names, userProperties,
//                                                                     matchAllNames);
//        setAdditionalProperties(sref, userProperties);
//
//        if (srefs.isEmpty()) {
//            return new ServiceEndpointDescriptionImpl(Arrays.asList(names), userProperties);
//        }
//
//        return srefs.get(0);
//    }

//    @SuppressWarnings("unchecked")
//    public static List<ServiceEndpointDescription> getRemoteReferences(Bundle b, String[] names,
//                                                                       Map<String, Object> userProperties,
//                                                                       boolean matchAllNames) {
//
//        List<Element> references = getAllDescriptionElements(b);
//
//        List<ServiceEndpointDescription> srefs = new ArrayList<ServiceEndpointDescription>();
//        Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
//        for (Element ref : references) {
//            List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
//            if (!serviceNamesMatch(names, iNames, matchAllNames)) {
//                continue;
//            }
//
//            Map<String, Object> remoteProps = new HashMap<String, Object>(userProperties);
//            addProperties(remoteProps, ref.getChildren(PROPERTY_ELEMENT, ns));
//            srefs.add(new ServiceEndpointDescriptionImpl(iNames, remoteProps));
//        }
//        return srefs;
//
//    }

//    public static ServiceEndpointDescription[] flattenServiceDescription(ServiceEndpointDescription sd) {
//        ServiceEndpointDescription[] list = null;
//        int interfaceNameCount = sd.getProvidedInterfaces().size();
//        if (sd.getProvidedInterfaces() == null || interfaceNameCount <= 1) {
//            list = new ServiceEndpointDescription[] {
//                sd
//            };
//        } else {
//            String[] iNames = (String[])sd.getProvidedInterfaces().toArray(new String[interfaceNameCount]);
//            list = new ServiceEndpointDescription[iNames.length];
//            for (int i = 0; i < iNames.length; i++) {
//                Map<String, Object> props = excludeProperty(sd.getProperties(),
//                                                            Constants.EXPORTED_INTERFACES,
//                                                            Constants.EXPORTED_INTERFACES_OLD,
//                                                            Constants.RS_PROVIDER_GLOBAL_PROP_KEY,
//                                                            Constants.RS_PROVIDER_EXPECTED_PROP_KEY,
//                                                            Constants.RS_PROVIDER_PROP_KEY);
//
//                String keys[] = props.keySet().toArray(new String[props.size()]);
//                for (int j = 0; j < keys.length; j++) {
//                    int sep = keys[j].indexOf(INTERFACE_SEPARATOR);
//                    if (sep > -1) {
//                        String value = (String)props.remove(keys[j]);
//                        String root = keys[j].substring(0, sep);
//                        String iface = sep + INTERFACE_SEPARATOR.length() < keys[j].length() ? keys[j]
//                            .substring(sep + INTERFACE_SEPARATOR.length()) : "";
//                        if (iNames[i].equals(iface)) {
//                            props.put(root, value);
//                        }
//                    }
//                }
//                list[i] = new ServiceEndpointDescriptionImpl(iNames[i], props);
//            }
//        }
//        return list;
//    }

//    private static Map<String, Object> excludeProperty(Map properties, String... excludes) {
//        Collection<String> exList = Arrays.asList(excludes);
//
//        Map<String, Object> pruned = new HashMap<String, Object>();
//        for (Object key : properties.keySet()) {
//            if (exList.contains(key)) {
//                // exclude
//            } else {
//                pruned.put((String)key, properties.get(key));
//            }
//        }
//        return pruned;
//    }

    @SuppressWarnings("unchecked")
    public static List<Element> getAllDescriptionElements(Bundle b) {
        Object directory = null;

        Dictionary headers = b.getHeaders();
        if (headers != null) {
            directory = headers.get(REMOTE_SERVICES_HEADER_NAME);
        }

        if (directory == null) {
            directory = REMOTE_SERVICES_DIRECTORY;
        }

        Enumeration urls = b.findEntries(directory.toString(), "*.xml", false);
        if (urls == null) {
            return Collections.emptyList();
        }

        List<Element> elements = new ArrayList<Element>();
        while (urls.hasMoreElements()) {
            URL resourceURL = (URL)urls.nextElement();
            try {
                Document d = new SAXBuilder().build(resourceURL.openStream());
                Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
                elements.addAll(d.getRootElement().getChildren(SERVICE_DESCRIPTION_ELEMENT, ns));
            } catch (Exception ex) {
                LOG.log(Level.WARNING, "Problem parsing: " + resourceURL, ex);
            }
        }
        return elements;
    }

//    private static void setAdditionalProperties(ServiceReference sref, Map<String, Object> props) {
//        BundleContext bc = sref.getBundle().getBundleContext();
//        ServiceReference[] refs;
//        try {
//            refs = bc.getServiceReferences(ServiceDecorator.class.getName(), null);
//        } catch (InvalidSyntaxException e) {
//            // should never happen, filter is null
//            return;
//        }
//        if (refs == null) {
//            return;
//        }
//
//        for (ServiceReference ref : refs) {
//            Object svc = bc.getService(ref);
//            if (svc instanceof ServiceDecorator) {
//                ((ServiceDecorator)svc).decorate(sref, props);
//            }
//        }
//    }

//    private static boolean serviceNamesMatch(String[] names, List<String> iNames, boolean matchAllNames) {
//        if (names == null || names.length == 0) {
//            return false;
//        }
//        if (matchAllNames) {
//            for (String name : names) {
//                if (!iNames.contains(name)) {
//                    return false;
//                }
//            }
//            return true;
//        } else {
//            for (String name : names) {
//                if (iNames.contains(name)) {
//                    return true;
//                }
//            }
//            return false;
//        }
//    }

    /*
     * // TODO : consider creating a new List rather than modifyiing the existing one public static void
     * matchServiceDescriptions(List<ServiceEndpointDescription> sds, String interfaceName, Filter filter,
     * boolean matchAll) { for (Iterator<ServiceEndpointDescription> it = sds.iterator(); it.hasNext();) {
     * ServiceEndpointDescription sd = it.next(); if (filter != null && !OsgiUtils.matchAgainstFilter(sd,
     * interfaceName, filter, matchAll)) { it.remove(); } } }
     * @SuppressWarnings("unchecked") public static boolean matchAgainstFilter(ServiceEndpointDescription sd,
     * String interfaceName, Filter filter, boolean matchAll) { Dictionary props = new Hashtable(); for
     * (Object key : sd.getPropertyKeys()) { if (matchAll ||
     * key.toString().startsWith(DistributionConstants.REMOTE)) { props.put(key,
     * sd.getProperty(key.toString())); } } String[] interfaceNames = getProvidedInterfaces(sd,
     * interfaceName); if (interfaceNames != null) { props.put(org.osgi.framework.Constants.OBJECTCLASS,
     * interfaceNames); } return filter.match(props); }
     */

//    public static String[] getProvidedInterfaces(ServiceEndpointDescription sd, String interfaceName) {
//
//        int interfaceNameCount = sd.getProvidedInterfaces().size();
//        String[] interfaceNames = (String[])sd.getProvidedInterfaces()
//            .toArray(new String[interfaceNameCount]);
//        if (interfaceName == null) {
//            return interfaceNames;
//        }
//
//        for (String s : interfaceNames) {
//            if (s.equals(interfaceName)) {
//                return new String[] {
//                    s
//                };
//            }
//        }
//        return null;
//    }

    public static Filter createFilter(BundleContext bc, String filterValue) {

        if (filterValue == null) {
            return null;
        }

        try {
            return bc.createFilter(filterValue);
        } catch (InvalidSyntaxException ex) {
            System.out.println("Invalid filter expression " + filterValue);
        } catch (Exception ex) {
            System.out.println("Problem creating a Filter from " + filterValue);
        }
        return null;
    }

    public static String[] parseIntents(String intentsSequence) {
        return intentsSequence == null ? new String[] {} : intentsSequence.split(" ");
    }

    public static String formatIntents(String[] intents) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String intent : intents) {
            if (first) {
                first = false;
            } else {
                sb.append(' ');
            }
            sb.append(intent);
        }
        return sb.toString();
    }

//    private static Map<String, Object> getProperties(List<Element> elements) {
//        Map<String, Object> props = new HashMap<String, Object>();
//        addProperties(props, elements);
//        return props;
//    }

//    private static void addProperties(Map<String, Object> props, List<Element> elements) {
//        for (Element p : elements) {
//            String key = p.getAttributeValue(PROPERTY_NAME_ATTRIBUTE);
//            String value = p.getAttributeValue(PROPERTY_VALUE_ATTRIBUTE);
//            if (value == null) {
//                value = p.getTextTrim();
//            }
//
//            String iface = p.getAttributeValue(PROPERTY_INTERFACE_ATTRIBUTE);
//            if (key != null) {
//                props.put(iface == null || iface.length() == 0 ? key : key + INTERFACE_SEPARATOR + iface,
//                          value);
//            }
//        }
//    }

//    private static List<String> getProvidedInterfaces(List<Element> elements) {
//
//        List<String> names = new ArrayList<String>();
//
//        for (Element p : elements) {
//            String name = p.getAttributeValue(PROVIDE_INTERFACE_NAME_ATTRIBUTE);
//            if (name != null) {
//                names.add(name);
//            }
//        }
//
//        return names;
//    }

    @SuppressWarnings("unchecked")
    public static <T> OsgiService<T> getOsgiService(BundleContext bc, Class<T> serviceClass) {
        try {
            ServiceReference sr = bc.getServiceReference(serviceClass.getName());
            if (sr != null) {
                Object o = bc.getService(sr);
                if (o != null && serviceClass.isAssignableFrom(o.getClass())) {
                    return new OsgiService(sr, o);
                }
            }
        } catch (Exception ex) {
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("Problem retrieving an OSGI service " + serviceClass.getName() + ", exception : "
                         + ex.getMessage());
            }
        }
        return null;
    }

    public static IntentMap getIntentMap(BundleContext bundleContext) {
        IntentMap im = readIntentMap(bundleContext);
        if (im == null) {
            // Couldn't read an intent map
            LOG.log(Level.FINE, "Using default intent map");
            im = new IntentMap();
            im.setIntents(new HashMap<String, Object>());
        }
        return im;
    }

    static IntentMap readIntentMap(BundleContext bundleContext) {
        List<String> springIntentLocations = new ArrayList<String>();
        for (String mapFile : INTENT_MAP) {
            if (bundleContext.getBundle().getResource(mapFile) == null) {
                LOG.info("Could not find intent map file " + mapFile);
                return null;
            }
            springIntentLocations.add("classpath:" + mapFile);
        }

        try {
           
            // switch to cxf bundle classloader for spring
            Thread.currentThread().setContextClassLoader(PolicyNamespaceHandler.class.getClassLoader());
           
            LOG.fine("Loading Intent map from "+springIntentLocations);
            System.out.println("Loading Intent map from "+springIntentLocations);
            OsgiBundleXmlApplicationContext ctx = new OsgiBundleXmlApplicationContext(springIntentLocations
                .toArray(new String[] {}));
            ctx.setPublishContextAsService(false);
            ctx.setBundleContext(bundleContext);
            ctx.refresh();
            LOG.fine("application context: " + ctx);
            System.out.println("application context: " + ctx);
            IntentMap im = (IntentMap)ctx.getBean("intentMap");
            LOG.fine("retrieved intent map: " + im);
            System.out.println("retrieved intent map: " + im);
            // switch back
            Thread.currentThread().setContextClassLoader(RemoteServiceAdminCore.class.getClassLoader());
           
            return im;
        } catch (Throwable t) {
            LOG.log(Level.WARNING, "Intent map load failed: ", t);
            return null;
        }
    }

    // Eg. "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
    public static Filter createFilterFromProperties(BundleContext bc, Dictionary properties) {

        if (properties == null || properties.isEmpty()) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("(&");
        for (Enumeration keys = properties.keys(); keys.hasMoreElements();) {
            String key = keys.nextElement().toString();
            String value = properties.get(key).toString();
            sb.append('(').append(key).append('=').append(value).append(')');
        }
        sb.append(')');
        return createFilter(bc, sb.toString());
    }

    // TODO : move these property helpers into PropertyUtils ?

    public static boolean getBooleanProperty(Map sd, String name) {
        Object value = sd.get(name);
        return toBoolean(value);
    }

    public static boolean toBoolean(Object value) {
        return value instanceof Boolean && ((Boolean)value).booleanValue() || value instanceof String
               && Boolean.parseBoolean((String)value);
    }

    @SuppressWarnings("unchecked")
    public static Collection<String> getMultiValueProperty(Object property) {
        if (property == null) {
            return null;
        }

        if (property instanceof Collection) {
            return (Collection<String>)property;
        } else if (property instanceof String[]) {
            return Arrays.asList((String[])property);
        } else {
            return Collections.singleton(property.toString());
        }
    }

    public static String getProperty(EndpointDescription sd, String name) {
        Object o = sd.getProperties().get(name);

        if (o != null && o instanceof String) {
            return (String)o;
        }

        return null;

    }

    public static String getProperty(Map dict, String name) {
        Object o = dict.get(name);

        if (o != null && o instanceof String) {
            return (String)o;
        }
        return null;
    }

//    @SuppressWarnings("unchecked")
//    public static <T> T getProperty(ServiceEndpointDescription sd, String name, Class<T> type, T defaultValue) {
//        Object o = sd.getProperty(name);
//        if (o == null) {
//            return defaultValue;
//        }
//        return type.isAssignableFrom(o.getClass()) ? (T)o : null;
//    }
//
//    public static String[] getPublishableInterfaces(ServiceEndpointDescription sd, ServiceReference sref) {
//        Collection<String> publishProperty = getMultiValueProperty(sd
//            .getProperty(Constants.EXPORTED_INTERFACES));
//        if (publishProperty == null) {
//            publishProperty = getMultiValueProperty(sd.getProperty(Constants.EXPORTED_INTERFACES_OLD));
//        }
//
//        String[] actualInterfaces = (String[])sref.getProperty(org.osgi.framework.Constants.OBJECTCLASS);
//        String[] publishableInterfaces = null;
//
//        if (actualInterfaces != null && actualInterfaces.length > 0 && publishProperty != null) {
//
//            if (publishProperty.size() == 1 && INTERFACE_WILDCARD.equals(publishProperty.iterator().next())) {
//                // wildcard indicates all interfaces should be published
//                //
//                publishableInterfaces = actualInterfaces;
//            } else {
//                String[] requestedInterfaces;
//                if (publishProperty.size() == 0) {
//                    requestedInterfaces = null;
//                } else if (publishProperty.size() == 1) {
//                    requestedInterfaces = tokenize(publishProperty.iterator().next(), ",");
//                } else {
//                    requestedInterfaces = publishProperty.toArray(new String[publishProperty.size()]);
//                }
//
//                ArrayList<String> publishableList = new ArrayList<String>();
//                for (int i = 0; requestedInterfaces != null && i < requestedInterfaces.length; i++) {
//                    if (contains(actualInterfaces, requestedInterfaces[i])) {
//                        publishableList.add(requestedInterfaces[i]);
//                    } else {
//                        // simply ignore non-exposed interfaces
//                        //
//                        LOG.warning("ignoring publish interface, " + requestedInterfaces[i]
//                                    + ", not exposed by service");
//                    }
//                }
//
//                if (publishableList.size() > 0) {
//                    publishableInterfaces = publishableList.toArray(new String[publishableList.size()]);
//                }
//            }
//        }
//
//        return publishableInterfaces;
//    }

//    private static String[] tokenize(String str, String delim) {
//        StringTokenizer tokenizer = new StringTokenizer(str, delim);
//        String[] tokens = new String[tokenizer.countTokens()];
//        for (int i = 0; tokenizer.hasMoreTokens(); i++) {
//            tokens[i] = tokenizer.nextToken();
//        }
//        return tokens;
//    }
//
//    private static boolean contains(String[] list, String member) {
//        boolean found = false;
//        for (int i = 0; i < list.length && !found; i++) {
//            found = member.equals(list[i]);
//        }
//        return found;
//    }

    /**
     * Tries to retrieve the version of iClass via the PackageAdmin
     *
     * @param iClass - The interface for which the version should be found
     * @param bc - any valid BundleContext
     * @return the version of the interface or "0.0.0" if no version information could be found or an error
     *         occurred during the retrieval
     */
    public static String getVersion(Class<?> iClass, BundleContext bc) {

        ServiceReference paRef = bc.getServiceReference(PackageAdmin.class.getName());
        if (paRef != null) {
            PackageAdmin pa = (PackageAdmin)bc.getService(paRef);

            Bundle b = pa.getBundle(iClass);
            if (b == null) {
                LOG.info("Unable to find interface version for interface " + iClass.getName()
                        + ". Falling back to 0.0.0");
                return "0.0.0";
            }
            LOG.finest("Interface source bundle: " + b.getSymbolicName());

            ExportedPackage[] ep = pa.getExportedPackages(b);
            LOG.finest("Exported Packages of the source bundle: " + ep);

            String pack = iClass.getPackage().getName();
            LOG.finest("Looking for Package: " + pack);

            for (ExportedPackage p : ep) {
                if (pack.equals(p.getName())) {
                    LOG.fine("found package -> Version: " + p.getVersion());
                    return p.getVersion().toString();
                }
            }
        } else {
            LOG.severe("Was unable to obtain the package admin service -> can't resolve interface versions");
        }

        LOG.info("Unable to find interface version for interface " + iClass.getName()
                 + ". Falling back to 0.0.0");
        return "0.0.0";
    }

   
    public static String getUUID(BundleContext bc) {
        synchronized ("org.osgi.framework.uuid") {
            String uuid = bc.getProperty("org.osgi.framework.uuid");
            if (uuid == null) {
                uuid = UUID.randomUUID().toString();
                System.setProperty("org.osgi.framework.uuid", uuid);
            }
            return uuid;
        }
    }
   
}
TOP

Related Classes of org.apache.cxf.dosgi.dsw.OsgiUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.