org.springframework.ide.eclipse.beans.ui.namespaces.NamespaceUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.beans.ui.namespaces.NamespaceUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2006, 2011 Spring IDE Developers
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Spring IDE Developers - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.namespaces;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.model.INamespaceDefinitionResolver;
import org.springframework.ide.eclipse.beans.ui.BeansUIImages;
import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin;
import org.springframework.ide.eclipse.beans.ui.namespaces.DefaultNamespaceDefinition.Version;
import org.springframework.ide.eclipse.core.model.ISourceModelElement;
import org.springframework.ide.eclipse.core.model.ModelUtils;
import org.springframework.util.StringUtils;

/**
 * Some helper methods.
 * @author Torsten Juergeleit
 * @author Christian Dupuis
 */
public class NamespaceUtils {

    public static final String NAMESPACES_EXTENSION_POINT = BeansUIPlugin.PLUGIN_ID + ".namespaces";

    public static final String DEFAULT_NAMESPACE_URI = "http://www.springframework.org/schema/beans";

    public static final String TOOLS_NAMESPACE_URI = "http://www.springframework.org/schema/tool";

    public static final String P_NAMESPACE_URI = "http://www.springframework.org/schema/p";

    public static final String C_NAMESPACE_URI = "http://www.springframework.org/schema/c";

    private static final Object IMAGE_REGISTRY_LOCK = new Object();

    private static final INamespaceDefinition P_NAMESPACE_DEFINITION = new DefaultNamespaceDefinition("p",
            P_NAMESPACE_URI, null,
            new DefaultImageAccessor(BeansUIPlugin.PLUGIN_ID, "/icons/full/obj16/property_obj.gif"));

    private static final INamespaceDefinition C_NAMESPACE_DEFINITION = new DefaultNamespaceDefinition("c",
            C_NAMESPACE_URI, null,
            new DefaultImageAccessor(BeansUIPlugin.PLUGIN_ID, "/icons/full/obj16/constructor_obj.gif"));

    /**
     * Returns the namespace URI for the given {@link ISourceModelElement} or
     * <code>"http://www.springframework.org/schema/beans"</code> if no namespace URI found.
     */
    public static String getNameSpaceURI(ISourceModelElement element) {
        String namespaceURI = ModelUtils.getNameSpaceURI(element);
        if (namespaceURI == null) {
            namespaceURI = DEFAULT_NAMESPACE_URI;
        }
        return namespaceURI;
    }

    /**
     * Returns the {@link INamespaceLabelProvider} for the given {@link ISourceModelElement}'s namespace.
     */
    public static INamespaceLabelProvider getLabelProvider(ISourceModelElement element) {
        IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(NAMESPACES_EXTENSION_POINT);
        if (point != null) {
            String namespaceURI = getNameSpaceURI(element);
            for (IExtension extension : point.getExtensions()) {
                for (IConfigurationElement config : extension.getConfigurationElements()) {
                    if (namespaceURI.equals(config.getAttribute("uri"))) {
                        if (config.getAttribute("labelProvider") != null) {
                            try {
                                Object provider = config.createExecutableExtension("labelProvider");
                                if (provider instanceof INamespaceLabelProvider) {
                                    return (INamespaceLabelProvider) provider;
                                }
                            } catch (CoreException e) {
                                BeansUIPlugin.log(e);
                            }
                        }
                        return null;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Returns the {@link ITreeContentProvider} for the given {@link ISourceModelElement}'s namespace.
     */
    public static ITreeContentProvider getContentProvider(ISourceModelElement element) {
        IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(NAMESPACES_EXTENSION_POINT);
        if (point != null) {
            String namespaceURI = getNameSpaceURI(element);
            for (IExtension extension : point.getExtensions()) {
                for (IConfigurationElement config : extension.getConfigurationElements()) {
                    if (namespaceURI.equals(config.getAttribute("uri"))) {
                        if (config.getAttribute("contentProvider") != null) {
                            try {
                                Object provider = config.createExecutableExtension("contentProvider");
                                if (provider instanceof IContentProvider) {
                                    return (ITreeContentProvider) provider;
                                }
                            } catch (CoreException e) {
                                BeansUIPlugin.log(e);
                            }
                        }
                        return null;
                    }
                }
            }
        }
        return null;
    }

    public static List<INamespaceDefinition> getNamespaceDefinitions() {
        return getNamespaceDefinitions(null);
    }

    public static List<INamespaceDefinition> getNamespaceDefinitions(final IProject project,
            final INamespaceDefinitionTemplate definitionTemplate) {
        if (definitionTemplate != null) {

            Job namespaceDefinitionJob = new Job(
                    (project != null ? String.format("Loading namespaces for project '%s'", project.getName())
                            : "Loading namespaces")) {

                @Override
                protected IStatus run(IProgressMonitor monitor) {
                    List<INamespaceDefinition> namespaceDefinitions = getNamespaceDefinitions(project);
                    definitionTemplate
                            .doWithNamespaceDefinitions(
                                    (INamespaceDefinition[]) namespaceDefinitions
                                            .toArray(new INamespaceDefinition[namespaceDefinitions.size()]),
                                    project);
                    return Status.OK_STATUS;
                }
            };
            namespaceDefinitionJob.setPriority(Job.INTERACTIVE);
            namespaceDefinitionJob.schedule();

            return Collections.emptyList();
        }
        return getNamespaceDefinitions(project);
    }

    protected static List<INamespaceDefinition> getNamespaceDefinitions(IProject project) {
        List<INamespaceDefinition> namespaceDefinitions = new ArrayList<INamespaceDefinition>();

        INamespaceDefinitionResolver definitionResolver = BeansCorePlugin.getNamespaceDefinitionResolver(project);
        Set<org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition> detectedNamespaceDefinitions = definitionResolver
                .getNamespaceDefinitions();

        IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(NAMESPACES_EXTENSION_POINT);
        if (point != null && !org.springframework.ide.eclipse.beans.core.namespaces.NamespaceUtils
                .useNamespacesFromClasspath(project)) {
            for (IExtension extension : point.getExtensions()) {
                for (IConfigurationElement config : extension.getConfigurationElements()) {
                    String uri = config.getAttribute("uri");
                    org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition namespaceDefinition = definitionResolver
                            .resolveNamespaceDefinition(uri);
                    detectedNamespaceDefinitions.remove(namespaceDefinition);

                    String prefix = config.getAttribute("prefix");
                    if (!StringUtils.hasText(prefix) && namespaceDefinition != null) {
                        prefix = namespaceDefinition.getPrefix();
                    }
                    String schemaLocation = config.getAttribute("defaultSchemaLocation");
                    if (!StringUtils.hasText(schemaLocation) && namespaceDefinition != null) {
                        schemaLocation = namespaceDefinition.getDefaultSchemaLocation();
                    }
                    IImageAccessor image = null;
                    if (config.getAttribute("icon") != null) {
                        String ns = config.getDeclaringExtension().getNamespaceIdentifier();
                        String icon = config.getAttribute("icon");
                        image = new DefaultImageAccessor(ns, icon);
                    } else if (namespaceDefinition != null) {
                        image = new NamespaceDefinitionImageAccessor(namespaceDefinition);
                    }

                    DefaultNamespaceDefinition def = null;
                    if (namespaceDefinition != null) {
                        def = new DefaultNamespaceDefinition(prefix, uri, schemaLocation,
                                namespaceDefinition.getUriMapping(), image);
                    } else {
                        def = new DefaultNamespaceDefinition(prefix, uri, schemaLocation, new Properties(), image);
                    }

                    // get schema locations from nested child elements
                    IConfigurationElement[] schemaLocationConfigElements = config.getChildren("schemaLocation");
                    for (IConfigurationElement schemaLocationConfigElement : schemaLocationConfigElements) {
                        def.addSchemaLocation(schemaLocationConfigElement.getAttribute("url"));
                    }
                    if (def.getSchemaLocations().size() == 0 && namespaceDefinition != null) {
                        def.getSchemaLocations().addAll(namespaceDefinition.getSchemaLocations());
                    }

                    namespaceDefinitions.add(def);
                }
            }
        }

        for (org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition namespaceDefinition : detectedNamespaceDefinitions) {
            DefaultNamespaceDefinition def = new DefaultNamespaceDefinition(namespaceDefinition.getPrefix(),
                    namespaceDefinition.getNamespaceUri(), namespaceDefinition.getDefaultSchemaLocation(),
                    namespaceDefinition.getUriMapping(), new NamespaceDefinitionImageAccessor(namespaceDefinition));
            def.getSchemaLocations().addAll(namespaceDefinition.getSchemaLocations());
            namespaceDefinitions.add(def);
        }

        boolean foundPNamespace = false;
        boolean foundCNamespace = false;
        INamespaceDefinition defaultNamespace = null;

        // Remove the tool namespace as we don't want to surface on the UI
        for (INamespaceDefinition definition : new ArrayList<INamespaceDefinition>(namespaceDefinitions)) {
            if (TOOLS_NAMESPACE_URI.equals(definition.getNamespaceURI())) {
                namespaceDefinitions.remove(definition);
            } else if (DEFAULT_NAMESPACE_URI.equals(definition.getNamespaceURI())) {
                defaultNamespace = definition;
            } else if (P_NAMESPACE_URI.equals(definition.getNamespaceURI())) {
                foundPNamespace = true;
            } else if (C_NAMESPACE_URI.equals(definition.getNamespaceURI())) {
                foundCNamespace = true;
            }
        }

        if (!foundPNamespace && defaultNamespace != null) {
            // Add in p-Namespace if we found the default namespace
            namespaceDefinitions.add(P_NAMESPACE_DEFINITION);
        }
        if (!foundCNamespace && defaultNamespace != null) {
            // Add in c-Namespace if we found the default namespace
            // && is Spring 3.1 or greater
            Set<String> locations = defaultNamespace.getSchemaLocations();
            for (String locationUri : locations) {
                if (isSpring31(locationUri)) {
                    namespaceDefinitions.add(C_NAMESPACE_DEFINITION);
                    break;
                }
            }
        }

        Collections.sort(namespaceDefinitions, new Comparator<INamespaceDefinition>() {
            public int compare(INamespaceDefinition o1, INamespaceDefinition o2) {
                if (o1 != null && o1.getDefaultNamespacePrefix() != null && o2 != null
                        && o2.getDefaultNamespacePrefix() != null) {
                    return o1.getDefaultNamespacePrefix().compareTo(o2.getDefaultNamespacePrefix());
                }
                return 0;
            }
        });

        return namespaceDefinitions;
    }

    private static boolean isSpring31(String locationUri) {
        Version minimum = new Version("3.1");
        Version temp = Version.MINIMUM_VERSION;
        Matcher matcher = DefaultNamespaceDefinition.VERSION_PATTERN.matcher(locationUri);
        if (matcher.matches()) {
            temp = new Version(matcher.group(1));
        }
        if (temp.compareTo(minimum) >= 0) {
            return true;
        }
        return false;
    }

    public static INamespaceDefinition getDefaultNamespaceDefinition() {
        INamespaceDefinitionResolver definitionResolver = BeansCorePlugin.getNamespaceDefinitionResolver(null);
        org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition namespaceDefinition = definitionResolver
                .resolveNamespaceDefinition(DEFAULT_NAMESPACE_URI);

        IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(NAMESPACES_EXTENSION_POINT);
        if (point != null) {
            String namespaceURI = DEFAULT_NAMESPACE_URI;
            for (IExtension extension : point.getExtensions()) {
                for (IConfigurationElement config : extension.getConfigurationElements()) {
                    if (namespaceURI.equals(config.getAttribute("uri"))) {

                        String prefix = config.getAttribute("prefix");
                        if (!StringUtils.hasText(prefix) && namespaceDefinition != null) {
                            prefix = namespaceDefinition.getPrefix();
                        }
                        String schemaLocation = config.getAttribute("defaultSchemaLocation");
                        if (!StringUtils.hasText(schemaLocation) && namespaceDefinition != null) {
                            schemaLocation = namespaceDefinition.getDefaultSchemaLocation();
                        }
                        String uri = config.getAttribute("uri");
                        IImageAccessor image = null;
                        if (config.getAttribute("icon") != null) {
                            String ns = config.getDeclaringExtension().getNamespaceIdentifier();
                            String icon = config.getAttribute("icon");
                            image = new DefaultImageAccessor(ns, icon);
                        } else if (namespaceDefinition != null) {
                            image = new NamespaceDefinitionImageAccessor(namespaceDefinition);
                        }
                        return new DefaultNamespaceDefinition(prefix, uri, schemaLocation,
                                namespaceDefinition.getUriMapping(), image);
                    }
                }
            }
        }

        if (namespaceDefinition != null) {
            return new DefaultNamespaceDefinition(namespaceDefinition.getPrefix(),
                    namespaceDefinition.getNamespaceUri(), namespaceDefinition.getDefaultSchemaLocation(),
                    namespaceDefinition.getUriMapping(), new NamespaceDefinitionImageAccessor(namespaceDefinition));
        }
        return null;
    }

    /**
     * Returns an {@link Image} instance which is located at the indicated icon path.
     */
    public static Image getImage(
            org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition namespaceDefinition) {
        if (StringUtils.hasText(namespaceDefinition.getIconPath())) {
            synchronized (IMAGE_REGISTRY_LOCK) {
                Image image = BeansUIPlugin.getDefault().getImageRegistry().get(namespaceDefinition.getIconPath());
                if (image == null) {
                    InputStream is = namespaceDefinition.getIconStream();
                    if (is != null) {
                        try {
                            ImageDescriptor imageDescriptor = ImageDescriptor
                                    .createFromImageData(new ImageData(is));
                            BeansUIPlugin.getDefault().getImageRegistry().put(namespaceDefinition.getIconPath(),
                                    imageDescriptor);
                            image = BeansUIPlugin.getDefault().getImageRegistry()
                                    .get(namespaceDefinition.getIconPath());
                        } catch (Exception e) {
                            BeansUIPlugin.log(
                                    String.format("Error creating image resource for namespace definition '%s'",
                                            namespaceDefinition.getNamespaceUri()),
                                    e);
                            return BeansUIImages.getImage(BeansUIImages.IMG_OBJS_XSD);
                        } finally {
                            if (is != null) {
                                try {
                                    is.close();
                                } catch (IOException e) {
                                }
                            }
                        }
                    } else {
                        BeansUIPlugin.getDefault().getImageRegistry().put(namespaceDefinition.getIconPath(),
                                BeansUIImages.getImage(BeansUIImages.IMG_OBJS_XSD));
                        image = BeansUIPlugin.getDefault().getImageRegistry()
                                .get(namespaceDefinition.getIconPath());
                    }
                }
                return image;
            }
        } else {
            return BeansUIImages.getImage(BeansUIImages.IMG_OBJS_XSD);
        }
    }

    /**
     * Returns an {@link Image} instance which is located at the indicated icon path.
     */
    private static Image getImage(String ns, String icon) {
        if (StringUtils.hasText(icon)) {
            synchronized (IMAGE_REGISTRY_LOCK) {
                Image image = BeansUIPlugin.getDefault().getImageRegistry().get(icon);
                if (image == null) {
                    ImageDescriptor imageDescriptor = BeansUIPlugin.imageDescriptorFromPlugin(ns, icon);
                    BeansUIPlugin.getDefault().getImageRegistry().put(icon, imageDescriptor);
                    image = BeansUIPlugin.getDefault().getImageRegistry().get(icon);
                }
                return image;
            }
        } else {
            return BeansUIImages.getImage(BeansUIImages.IMG_OBJS_XSD);
        }
    }

    public interface INamespaceDefinitionTemplate {

        void doWithNamespaceDefinitions(INamespaceDefinition[] namespaceDefinitions, IProject project);

    }

    private static class DefaultImageAccessor extends DisplayThreadImageAccessor {

        private final String ns;

        private final String icon;

        public DefaultImageAccessor(String ns, String icon) {
            this.ns = ns;
            this.icon = icon;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected Image createImage() {
            return NamespaceUtils.getImage(ns, icon);
        }
    }

    private static class NamespaceDefinitionImageAccessor extends DisplayThreadImageAccessor {

        private final org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition definition;

        public NamespaceDefinitionImageAccessor(
                org.springframework.ide.eclipse.beans.core.model.INamespaceDefinition definition) {
            this.definition = definition;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected Image createImage() {
            return NamespaceUtils.getImage(definition);
        }
    }

}