Package org.apache.ivyde.eclipse.cpcontainer

Source Code of org.apache.ivyde.eclipse.cpcontainer.IvyClasspathContainerMapper$ArtifactMatcher

/*
*  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.ivyde.eclipse.cpcontainer;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivyde.eclipse.IvyPlugin;
import org.apache.ivyde.eclipse.resolve.ResolveResult;
import org.apache.ivyde.eclipse.workspaceresolver.WorkspaceResolver;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;

/**
* This class is mapping the resolved artifacts between them. After a resolve process, this class
* will build the classpath based on the retrieved artifacts and will search for sources and
* javadocs and make them attached.
*/
public class IvyClasspathContainerMapper {

    private static final String IVYDE_NS = "http://ant.apache.org/ivy/ivyde/ns/";

    private static final String IVYDE_NS_PREFIX = "ivyde:";

    private final IProgressMonitor monitor;

    private final Ivy ivy;

    private final IJavaProject javaProject;

    private final Collection/* <ArtifactDownloadReport> */all;

    private final Map/* <ModuleRevisionId, Artifact[]> */artifactsByDependency;

    private final Map/*
                      * <ArtifactDownloadReport , Set<String>>
                      */retrievedArtifacts;

    private ClasspathSetup classpathSetup;

    private MappingSetup mapping;

    public IvyClasspathContainerMapper(IProgressMonitor monitor, Ivy ivy,
            IvyClasspathContainerConfiguration conf, ResolveResult resolveResult) {
        this.monitor = monitor;
        this.ivy = ivy;
        this.javaProject = conf.getJavaProject();
        this.classpathSetup = conf.getInheritedClasspathSetup();
        this.mapping = conf.getInheritedMappingSetup();
        this.all = resolveResult.getArtifactReports();
        this.artifactsByDependency = resolveResult.getArtifactsByDependency();
        this.retrievedArtifacts = resolveResult.getRetrievedArtifacts();
    }

    public IClasspathEntry[] map() {
        IClasspathEntry[] classpathEntries;
        Collection paths = new LinkedHashSet();

        for (Iterator iter = all.iterator(); iter.hasNext();) {
            ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();

            if (artifact.getType().equals(WorkspaceResolver.ECLIPSE_PROJECT_TYPE)) {
                // This is a java project in the workspace, add project path
                // but only add it if it is not a self dependency
                if (javaProject == null
                        || !artifact.getName().equals(javaProject.getPath().toString())) {
                    paths.add(JavaCore.newProjectEntry(new Path(artifact.getName()), true));
                }
            } else if (artifact.getLocalFile() != null && accept(artifact.getArtifact())) {
                Path classpathArtifact = getArtifactPath(artifact);
                Path sourcesArtifact = getArtifactPath(artifact, sourceArtifactMatcher,
                    mapping.isMapIfOnlyOneSource());
                Path javadocArtifact = getArtifactPath(artifact, javadocArtifactMatcher,
                    mapping.isMapIfOnlyOneJavadoc());
                paths.add(JavaCore.newLibraryEntry(classpathArtifact,
                    getSourceAttachment(classpathArtifact, sourcesArtifact),
                    getSourceAttachmentRoot(classpathArtifact, sourcesArtifact), null,
                    getExtraAttribute(classpathArtifact, javadocArtifact), false));
            }

        }
        classpathEntries = (IClasspathEntry[]) paths.toArray(new IClasspathEntry[paths.size()]);

        return classpathEntries;
    }

    private Path getArtifactPath(ArtifactDownloadReport artifact) {
        if (retrievedArtifacts != null) {
            Set pathSet = (Set) retrievedArtifacts.get(artifact);
            if (pathSet != null && !pathSet.isEmpty()) {
                return new Path((String) pathSet.iterator().next());
            }
        }
        return new Path(artifact.getLocalFile().getAbsolutePath());
    }

    interface ArtifactMatcher {
        boolean matchName(Artifact artifact, String artifactName);

        boolean match(Artifact a);

        String getName();
    }

    private Path getArtifactPath(ArtifactDownloadReport adr, ArtifactMatcher matcher,
            boolean mapIfOnlyOne) {
        Artifact artifact = adr.getArtifact();
        monitor.subTask("searching " + matcher.getName() + " for " + artifact);
        for (Iterator iter = all.iterator(); iter.hasNext();) {
            ArtifactDownloadReport otherAdr = (ArtifactDownloadReport) iter.next();
            Artifact a = otherAdr.getArtifact();
            if (otherAdr.getLocalFile() != null && matcher.matchName(artifact, a.getName())
                    && a.getModuleRevisionId().equals(artifact.getModuleRevisionId())
                    && matcher.match(a)) {
                return getArtifactPath(otherAdr);
            }
        }
        // we haven't found source artifact in resolved artifacts,
        // let's look in the module declaring the artifact
        ModuleRevisionId mrid = artifact.getId().getModuleRevisionId();
        Artifact[] artifacts = (Artifact[]) artifactsByDependency.get(mrid);
        if (artifacts != null) {
            Artifact foundArtifact = null;
            int nbFound = 0;
            for (int i = 0; i < artifacts.length; i++) {
                Artifact metaArtifact = artifacts[i];
                if (matcher.match(metaArtifact)) {
                    if (matcher.matchName(artifact, metaArtifact.getName())) {
                        // we've found a matching artifact, let's provision it
                        ArtifactDownloadReport metaAdr = ivy.getResolveEngine().download(
                            metaArtifact, new DownloadOptions());
                        if (metaAdr.getLocalFile() != null && metaAdr.getLocalFile().exists()) {
                            return getArtifactPath(metaAdr);
                        }
                    }
                    // keep a reference to the artifact so we could fall back
                    // to map-if-only-one
                    nbFound++;
                    foundArtifact = metaArtifact;
                }
            }
            if (mapIfOnlyOne) {
                // we haven't found artifact in the module declaring the artifact and having
                // a matching name.
                if (nbFound == 1) {
                    // If there is only 1 found artifact, it is the winner ;-)
                    ArtifactDownloadReport metaAdr = ivy.getResolveEngine().download(foundArtifact,
                        new DownloadOptions());
                    if (metaAdr.getLocalFile() != null && metaAdr.getLocalFile().exists()) {
                        return new Path(metaAdr.getLocalFile().getAbsolutePath());
                    }
                }
            }
        }

        return null;
    }

    private ArtifactMatcher sourceArtifactMatcher = new ArtifactMatcher() {
        public boolean matchName(Artifact artifact, String source) {
            return isArtifactName(artifact, source, mapping.getSourceSuffixes(), "source");
        }

        public boolean match(Artifact a) {
            return mapping.getSourceTypes().contains(a.getType());
        }

        public String getName() {
            return "sources";
        }
    };

    private ArtifactMatcher javadocArtifactMatcher = new ArtifactMatcher() {
        public boolean matchName(Artifact artifact, String javadoc) {
            return isArtifactName(artifact, javadoc, mapping.getJavadocSuffixes(), "javadoc");
        }

        public boolean match(Artifact a) {
            return mapping.getJavadocTypes().contains(a.getType());
        }

        public String getName() {
            return "javadoc";
        }
    };

    private boolean isArtifactName(Artifact artifact, String name,
            Collection/* <String> */suffixes, String type) {
        String artifactNameToMatch = (String) artifact.getExtraAttribute(IVYDE_NS_PREFIX + type);
        if (artifactNameToMatch != null) {
            // some name is specified, it overrides suffix matching
            return name.equals(artifactNameToMatch);
        }
        String jar = artifact.getName();
        if (name.equals(jar)) {
            return true;
        }
        Iterator it = suffixes.iterator();
        while (it.hasNext()) {
            if (name.equals(jar + it.next())) {
                return true;
            }
        }
        return false;
    }

    private IPath getSourceAttachment(Path classpathArtifact, Path sourcesArtifact) {
        IPath sourceAttachment = IvyPlugin.getDefault().getPackageFragmentExtraInfo()
                .getSourceAttachment(classpathArtifact);
        if (sourceAttachment == null) {
            sourceAttachment = sourcesArtifact;
        }
        return sourceAttachment;
    }

    private IPath getSourceAttachmentRoot(Path classpathArtifact, Path sourcesArtifact) {
        IPath sourceAttachment = IvyPlugin.getDefault().getPackageFragmentExtraInfo()
                .getSourceAttachmentRoot(classpathArtifact);
        if (sourceAttachment == null && sourcesArtifact != null) {
            sourceAttachment = sourcesArtifact;
        }
        return sourceAttachment;
    }

    private IClasspathAttribute[] getExtraAttribute(Path classpathArtifact, Path javadocArtifact) {
        List result = new ArrayList();
        URL url = IvyPlugin.getDefault().getPackageFragmentExtraInfo()
                .getDocAttachment(classpathArtifact);

        if (url == null) {
            Path path = javadocArtifact;
            if (path != null) {
                String u;
                try {
                    u = "jar:" + path.toFile().toURL().toExternalForm() + "!/";
                    try {
                        url = new URL(u);
                    } catch (MalformedURLException e) {
                        // this should not happen
                        IvyPlugin.log(IStatus.ERROR,
                            "The jar URL for the javadoc is not formed correctly " + u, e);
                    }
                } catch (MalformedURLException e) {
                    // this should not happen
                    IvyPlugin.log(IStatus.ERROR, "The path has not a correct URL: " + path, e);
                }
            }
        }

        if (url != null) {
            result.add(JavaCore.newClasspathAttribute(
                IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, url.toExternalForm()));
        }
        return (IClasspathAttribute[]) result.toArray(new IClasspathAttribute[result.size()]);
    }

    /**
     * Check if the artifact is an artifact which can be added to the classpath container
     *
     * @param artifact
     *            the artifact to check
     * @return <code>true</code> if the artifact can be added
     */
    public boolean accept(Artifact artifact) {
        return classpathSetup.getAcceptedTypes().contains(artifact.getType())
                && !mapping.getSourceTypes().contains(artifact.getType())
                && !mapping.getJavadocTypes().contains(artifact.getType());
    }

}
TOP

Related Classes of org.apache.ivyde.eclipse.cpcontainer.IvyClasspathContainerMapper$ArtifactMatcher

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.