io.sarl.eclipse.util.Utilities.java Source code

Java tutorial

Introduction

Here is the source code for io.sarl.eclipse.util.Utilities.java

Source

/*
 * $Id$
 *
 * SARL is an general-purpose agent programming language.
 * More details on http://www.sarl.io
 *
 * Copyright (C) 2014-2017 the original authors or authors.
 *
 * Licensed 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 io.sarl.eclipse.util;

import com.google.common.base.Strings;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;

import io.sarl.lang.SARLConfig;

/** Utilities.
 *
 * @author $Author: sgalland$
 * @version $FullVersion$
 * @mavengroupid $GroupId$
 * @mavenartifactid $ArtifactId$
 */
public final class Utilities {

    /** Empty string.
     */
    public static final String EMPTY_STRING = ""; //$NON-NLS-1$

    private Utilities() {
        //
    }

    /** Null-safe version parser.
     *
     * @param version - the version string.
     * @return the version.
     */
    public static Version parseVersion(String version) {
        if (!Strings.isNullOrEmpty(version)) {
            try {
                return Version.parseVersion(version);
            } catch (Throwable exception) {
                //
            }
        }
        return null;
    }

    /** Null-safe compare a version number to a range of version numbers.
     *
     * <p>The minVersion must be strictly lower to the maxVersion. Otherwise
     * the behavior is not predictible.
     *
     * @param version - the version to compare to the range; must not be <code>null</code>.
     * @param minVersion - the minimal version in the range (inclusive); could be <code>null</code>.
     * @param maxVersion - the maximal version in the range (exclusive); could be <code>null</code>.
     * @return a negative number if the version in lower than the minVersion.
     *     A positive number if the version is greater than or equal to the maxVersion.
     *     <code>0</code> if the version is between minVersion and maxVersion.
     */
    public static int compareVersionToRange(Version version, Version minVersion, Version maxVersion) {
        assert minVersion == null || maxVersion == null || minVersion.compareTo(maxVersion) < 0;
        if (version == null) {
            return Integer.MIN_VALUE;
        }
        if (minVersion != null && compareVersionsNoQualifier(version, minVersion) < 0) {
            return -1;
        }
        if (maxVersion != null && compareVersionsNoQualifier(version, maxVersion) >= 0) {
            return 1;
        }
        return 0;
    }

    private static int compareVersionsNoQualifier(Version firstVersion, Version secondVersion) {
        if (firstVersion == secondVersion) {
            return 0;
        }

        int result = firstVersion.getMajor() - secondVersion.getMajor();
        if (result != 0) {
            return result;
        }

        result = firstVersion.getMinor() - secondVersion.getMinor();
        if (result != 0) {
            return result;
        }

        return firstVersion.getMicro() - secondVersion.getMicro();
    }

    /** Null-safe comparison.
     *
     * @param <T> - type of the comparable element.
     * @param object1 - the first object.
     * @param object2 - the second object.
     * @return Negative number if a lower than b.
     *     Positive number if a greater than b.
     * <code>0</code> if a is equal to b.
     */
    public static <T> int compareTo(Comparable<T> object1, T object2) {
        if (object1 == object2) {
            return 0;
        }
        if (object1 == null) {
            return Integer.MIN_VALUE;
        }
        if (object2 == null) {
            return Integer.MAX_VALUE;
        }
        assert object1 != null && object2 != null;
        return object1.compareTo(object2);
    }

    /** Replies the fully qualified name with generic parameters.
     *
     * @param type the type. Never <code>null</code>.
     * @return the qualified name.
     */
    public static String getNameWithTypeParameters(IType type) {
        assert type != null;
        final String superName = type.getFullyQualifiedName('.');
        if (!JavaModelUtil.is50OrHigher(type.getJavaProject())) {
            return superName;
        }
        try {
            final ITypeParameter[] typeParameters = type.getTypeParameters();
            if (typeParameters != null && typeParameters.length > 0) {
                final StringBuffer buf = new StringBuffer(superName);
                buf.append('<');
                for (int k = 0; k < typeParameters.length; ++k) {
                    if (k != 0) {
                        buf.append(',').append(' ');
                    }
                    buf.append(typeParameters[k].getElementName());
                }
                buf.append('>');
                return buf.toString();
            }
        } catch (JavaModelException e) {
            // ignore
        }
        return superName;

    }

    /** Create the classpath library linked to the bundle with the given name.
     *
     * @param bundle the bundle to point to. Never <code>null</code>.
     * @param precomputedBundlePath the path to the bundle that is already available. If <code>null</code>,
     *      the path is computed from the bundle with {@link BundleUtil}.
     * @param javadocURLs the mappings from the bundle to the javadoc URL. It is used for linking the javadoc to the bundle if
     *      the bundle platform does not know the Javadoc file. If <code>null</code>, no mapping is defined.
     * @return the classpath entry.
     */
    public static IClasspathEntry newLibraryEntry(Bundle bundle, IPath precomputedBundlePath,
            BundleURLMappings javadocURLs) {
        assert bundle != null;
        final IPath bundlePath;
        if (precomputedBundlePath == null) {
            bundlePath = BundleUtil.getBundlePath(bundle);
        } else {
            bundlePath = precomputedBundlePath;
        }
        final IPath sourceBundlePath = BundleUtil.getSourceBundlePath(bundle, bundlePath);
        final IPath javadocPath = BundleUtil.getJavadocBundlePath(bundle, bundlePath);

        final IClasspathAttribute[] extraAttributes;
        if (javadocPath == null) {
            if (javadocURLs != null) {
                final String url = javadocURLs.getURLForBundle(bundle);
                if (!Strings.isNullOrEmpty(url)) {
                    final IClasspathAttribute attr = JavaCore
                            .newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, url);
                    extraAttributes = new IClasspathAttribute[] { attr };
                } else {
                    extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
                }
            } else {
                extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
            }
        } else {
            final IClasspathAttribute attr = JavaCore.newClasspathAttribute(
                    IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, javadocPath.makeAbsolute().toOSString());
            extraAttributes = new IClasspathAttribute[] { attr };
        }

        return JavaCore.newLibraryEntry(bundlePath, sourceBundlePath, null, null, extraAttributes, false);
    }

    /** Create the classpath output location.
     *
     * @param bundle the bundle to point to. Never <code>null</code>.
     * @param precomputedBundlePath the path to the bundle that is already available. If <code>null</code>,
     *      the path is computed from the bundle with {@link BundleUtil}.
     * @param javadocURLs the mappings from the bundle to the javadoc URL. It is used for linking the javadoc to the bundle if
     *      the bundle platform does not know the Javadoc file. If <code>null</code>, no mapping is defined.
     * @return the classpath entry.
     */
    public static IClasspathEntry newOutputClasspathEntry(Bundle bundle, IPath precomputedBundlePath,
            BundleURLMappings javadocURLs) {
        assert bundle != null;
        final IPath bundlePath;
        if (precomputedBundlePath == null) {
            bundlePath = BundleUtil.getBundlePath(bundle);
        } else {
            bundlePath = precomputedBundlePath;
        }
        final IPath sourceBundlePath = BundleUtil.getSourceBundlePath(bundle, bundlePath);
        final IPath javadocPath = BundleUtil.getJavadocBundlePath(bundle, bundlePath);

        final IClasspathAttribute[] extraAttributes;
        if (javadocPath == null) {
            if (javadocURLs != null) {
                final String url = javadocURLs.getURLForBundle(bundle);
                if (!Strings.isNullOrEmpty(url)) {
                    final IClasspathAttribute attr = JavaCore
                            .newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, url);
                    extraAttributes = new IClasspathAttribute[] { attr };
                } else {
                    extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
                }
            } else {
                extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
            }
        } else {
            final IClasspathAttribute attr = JavaCore.newClasspathAttribute(
                    IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, javadocPath.makeAbsolute().toOSString());
            extraAttributes = new IClasspathAttribute[] { attr };
        }

        return new ClasspathEntry(ClasspathEntry.K_OUTPUT, IClasspathEntry.CPE_LIBRARY, bundlePath,
                ClasspathEntry.INCLUDE_ALL, ClasspathEntry.EXCLUDE_NONE, sourceBundlePath, null, null, false, null,
                false, extraAttributes);
    }

    /** Define a mapping from bundles to URLs.
     *
     * @author $Author: sgalland$
     * @version $FullVersion$
     * @mavengroupid $GroupId$
     * @mavenartifactid $ArtifactId$
     */
    @FunctionalInterface
    public interface BundleURLMappings {

        /** Replies the URL for the given bundle.
         *
         * @param bundle the bundle, never <code>null</code>.
         * @return the URL, or <code>null</code> if no URL is defined.
         */
        String getURLForBundle(Bundle bundle);

    }

    /** Define a mapping from bundles to URLs.
     *
     * @author $Author: sgalland$
     * @version $FullVersion$
     * @mavengroupid $GroupId$
     * @mavenartifactid $ArtifactId$
     */
    public static class SARLBundleJavadocURLMappings implements BundleURLMappings {

        private static final String SARL_PREFIX = "io.sarl."; //$NON-NLS-1$

        @Override
        public String getURLForBundle(Bundle bundle) {
            if (bundle.getSymbolicName().startsWith(SARL_PREFIX)) {
                return SARLConfig.JAVADOC_URL;
            }
            return null;
        }

    }

}