Package org.eclipse.tycho.source

Source Code of org.eclipse.tycho.source.OsgiSourceMojo

/*******************************************************************************
* Copyright (c) 2008, 2011 Sonatype Inc. and others.
* 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:
*    Sonatype Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.source;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.archiver.FileSet;
import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.codehaus.plexus.util.AbstractScanner;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.osgi.framework.Version;

/**
* Goal to create a JAR-package containing all the source files of a osgi project.
*
* @extendsPlugin source
* @extendsGoal jar
* @goal plugin-source
* @phase prepare-package
*/
public class OsgiSourceMojo extends AbstractSourceJarMojo {

    private static final String MANIFEST_HEADER_BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
    private static final String MANIFEST_HEADER_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
    private static final String MANIFEST_HEADER_BUNDLE_VERSION = "Bundle-Version";
    private static final String MANIFEST_HEADER_ECLIPSE_SOURCE_BUNDLE = "Eclipse-SourceBundle";
    private static final String VERSION_QUALIFIER = "qualifier";

    /**
     * If set to true, compiler will use source folders defined in build.properties file and will
     * ignore ${project.compileSourceRoots}/${project.testCompileSourceRoots}.
     *
     * Compilation will fail with an error, if this parameter is set to true but the project does
     * not have valid build.properties file.
     *
     * @parameter default-value="true"
     */
    private boolean usePdeSourceRoots;

    /**
     * Whether the source jar should be an Eclipse source bundle.
     *
     * @parameter default-value="true"
     */
    private boolean sourceBundle;

    /**
     * The suffix to be added to the symbolic name of the bundle to construct the symbolic name of
     * the Eclipse source bundle.
     *
     * @parameter expression="${sourceBundleSuffix}" default-value=".source"
     */
    private String sourceBundleSuffix;

    /**
     * Build qualifier. Recommended way to set this parameter is using build-qualifier goal. Only
     * used when creating a source bundle.
     *
     * @parameter expression="${buildQualifier}"
     */
    private String qualifier;

    /**
     * Whether default source excludes for SCM files defined in {@see
     * AbstractScanner#DEFAULTEXCLUDES} should be used.
     *
     * @parameter default-value="true"
     */
    protected boolean useDefaultSourceExcludes;

    /**
     * Whether source folders are required or not. If not required (the default), projects without
     * source folders will be silently ignored.
     *
     * @parameter default-value="false"
     * @readonly
     */
    protected boolean requireSourceRoots;

    /**
     * @component role="org.eclipse.tycho.core.TychoProject"
     */
    private Map<String, TychoProject> projectTypes;

    /** {@inheritDoc} */
    protected List<String> getSources(MavenProject p) throws MojoExecutionException {
        if (usePdeSourceRoots) {
            Properties props = getBuildProperties();
            List<String> sources = new ArrayList<String>();
            for (Entry<Object, Object> entry : props.entrySet()) {
                if (((String) entry.getKey()).startsWith("source.")) {
                    sources.addAll(getSourceDirs((String) entry.getValue()));
                }
            }
            if (requireSourceRoots && sources.isEmpty()) {
                throw new MojoExecutionException("no source folders found in build.properties");
            }
            return sources;
        } else {
            return p.getCompileSourceRoots();
        }
    }

    private List<String> getSourceDirs(String sourceRaw) {
        List<String> sources = new ArrayList<String>();
        for (String source : sourceRaw.split(",")) {
            sources.add(new File(project.getBasedir(), source.trim()).getAbsolutePath());
        }
        return sources;
    }

    /** {@inheritDoc} */
    protected List<Resource> getResources(MavenProject p) throws MojoExecutionException {
        if (excludeResources) {
            return Collections.emptyList();
        }
        if (usePdeSourceRoots) {
            Properties props = getBuildProperties();
            String srcIncludes = props.getProperty("src.includes");
            if (srcIncludes == null) {
                return Collections.emptyList();
            }
            List<String> srcInludesList = toFilePattern(props.getProperty("src.includes"));
            List<String> srcExcludesList = toFilePattern(props.getProperty("src.excludes"));
            //FileSet src = getFileSet(project.getBasedir(), includes, excludes);
            Resource resource = new Resource();
            resource.setDirectory(project.getBasedir().getAbsolutePath());
            resource.setExcludes(srcExcludesList);
            resource.setIncludes(srcInludesList);
            return Collections.singletonList(resource);
        }

        return p.getResources();
    }

    protected List<String> toFilePattern(String pattern) {
        ArrayList<String> result = new ArrayList<String>();
        if (pattern != null) {
            StringTokenizer st = new StringTokenizer(pattern, ",");
            while (st.hasMoreTokens()) {
                result.add(st.nextToken().trim());
            }
        }

        return result;
    }

    protected FileSet getFileSet(File basedir, List<String> includes, List<String> excludes) {
        DefaultFileSet fileSet = new DefaultFileSet();
        fileSet.setDirectory(basedir);
        fileSet.setIncludes(includes.toArray(new String[includes.size()]));

        Set<String> allExcludes = new LinkedHashSet<String>();
        if (excludes != null) {
            allExcludes.addAll(excludes);
        }
        if (useDefaultSourceExcludes) {
            allExcludes.addAll(Arrays.asList(AbstractScanner.DEFAULTEXCLUDES));
        }

        fileSet.setExcludes(allExcludes.toArray(new String[allExcludes.size()]));

        return fileSet;
    }

    /** {@inheritDoc} */
    protected String getClassifier() {
        return ReactorProject.SOURCE_ARTIFACT_CLASSIFIER;
    }

    // TODO check how to fix this code duplicated
    private Properties getBuildProperties() throws MojoExecutionException {
        File file = new File(project.getBasedir(), "build.properties");
        if (!file.canRead()) {
            throw new MojoExecutionException("Unable to read build.properties file");
        }

        Properties buildProperties = new Properties();
        try {
            InputStream is = new FileInputStream(file);
            try {
                buildProperties.load(is);
            } finally {
                is.close();
            }
        } catch (IOException e) {
            throw new MojoExecutionException("Exception reading build.properties file", e);
        }
        return buildProperties;
    }

    @Override
    protected void updateSourceManifest(MavenArchiveConfiguration mavenArchiveConfiguration) {
        super.updateSourceManifest(mavenArchiveConfiguration);

        if (sourceBundle) {
            addSourceBundleManifestEntries(mavenArchiveConfiguration);
        }
    }

    private void addSourceBundleManifestEntries(MavenArchiveConfiguration mavenArchiveConfiguration) {
        TychoProject projectType = projectTypes.get(project.getPackaging());
        ArtifactKey artifactKey = projectType.getArtifactKey(DefaultReactorProject.adapt(project));
        String symbolicName = artifactKey.getId();
        String version = artifactKey.getVersion();

        if (symbolicName != null && version != null) {
            mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_MANIFEST_VERSION, "2");

            mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_SYMBOLIC_NAME, symbolicName
                    + sourceBundleSuffix);

            Version expandedVersion = getExpandedVersion(version);

            mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_BUNDLE_VERSION, expandedVersion.toString());

            mavenArchiveConfiguration.addManifestEntry(MANIFEST_HEADER_ECLIPSE_SOURCE_BUNDLE, symbolicName
                    + ";version=\"" + expandedVersion + "\";roots:=\".\"");
        } else {
            getLog().info("NOT adding source bundle manifest entries. Incomplete or no bundle information available.");
        }
    }

    private Version getExpandedVersion(String versionStr) {
        Version version = Version.parseVersion(versionStr);
        if (VERSION_QUALIFIER.equals(version.getQualifier())) {
            return new Version(version.getMajor(), version.getMinor(), version.getMicro(), qualifier);
        }
        return version;
    }

    @Override
    protected boolean isRelevantProject(MavenProject project) {
        String packaging = project.getPackaging();
        boolean relevant = org.eclipse.tycho.ArtifactKey.TYPE_ECLIPSE_PLUGIN.equals(packaging)
                || org.eclipse.tycho.ArtifactKey.TYPE_ECLIPSE_TEST_PLUGIN.equals(packaging);
        if (!relevant) {
            return false;
        }
        try {
            return requireSourceRoots || !getSources(project).isEmpty();
        } catch (MojoExecutionException e) {
            // can't happen
        }
        return true;
    }

}
TOP

Related Classes of org.eclipse.tycho.source.OsgiSourceMojo

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.