001package org.apache.maven.extension.internal;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.io.IOException;
024import java.io.InputStream;
025import java.net.URL;
026import java.util.Collection;
027import java.util.Enumeration;
028import java.util.LinkedHashSet;
029import java.util.Set;
030
031import org.apache.maven.project.ExtensionDescriptor;
032import org.apache.maven.project.ExtensionDescriptorBuilder;
033import org.codehaus.plexus.classworlds.realm.ClassRealm;
034import org.codehaus.plexus.util.IOUtil;
035
036import com.google.common.collect.ImmutableSet;
037
038/**
039 * Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by
040 * Maven core itself or a Maven core extension.
041 * 
042 * @since 3.3.0
043 */
044public class CoreExtensionEntry
045{
046    private final ClassRealm realm;
047
048    private final Set<String> artifacts;
049
050    private final Set<String> packages;
051
052    public CoreExtensionEntry( ClassRealm realm, Collection<String> artifacts, Collection<String> packages )
053    {
054        this.realm = realm;
055        this.artifacts = ImmutableSet.copyOf( artifacts );
056        this.packages = ImmutableSet.copyOf( packages );
057    }
058
059    /**
060     * Returns ClassLoader used to load extension classes.
061     */
062    public ClassRealm getClassRealm()
063    {
064        return realm;
065    }
066
067    /**
068     * Returns artifacts exported by the extension, identified by groupId:artifactId string key.
069     */
070    public Set<String> getExportedArtifacts()
071    {
072        return artifacts;
073    }
074
075    /**
076     * Returns classpath elements exported by the extension.
077     */
078    public Set<String> getExportedPackages()
079    {
080        return packages;
081    }
082
083    private static final ExtensionDescriptorBuilder builder = new ExtensionDescriptorBuilder();
084
085    public static CoreExtensionEntry discoverFrom( ClassRealm loader )
086    {
087        Set<String> artifacts = new LinkedHashSet<String>();
088        Set<String> packages = new LinkedHashSet<String>();
089
090        try
091        {
092            Enumeration<URL> urls = loader.getResources( builder.getExtensionDescriptorLocation() );
093            while ( urls.hasMoreElements() )
094            {
095                InputStream is = urls.nextElement().openStream();
096                try
097                {
098                    ExtensionDescriptor descriptor = builder.build( is );
099                    artifacts.addAll( descriptor.getExportedArtifacts() );
100                    packages.addAll( descriptor.getExportedPackages() );
101                }
102                finally
103                {
104                    IOUtil.close( is );
105                }
106            }
107        }
108        catch ( IOException ignored )
109        {
110            // exports descriptors are entirely optional
111        }
112
113        return new CoreExtensionEntry( loader, artifacts, packages );
114    }
115
116    public static CoreExtensionEntry discoverFrom( ClassRealm loader, Collection<File> classpath )
117    {
118        Set<String> artifacts = new LinkedHashSet<String>();
119        Set<String> packages = new LinkedHashSet<String>();
120
121        try
122        {
123            for ( File entry : classpath )
124            {
125                ExtensionDescriptor descriptor = builder.build( entry );
126                if ( descriptor != null )
127                {
128                    artifacts.addAll( descriptor.getExportedArtifacts() );
129                    packages.addAll( descriptor.getExportedPackages() );
130                }
131            }
132        }
133        catch ( IOException ignored )
134        {
135            // exports descriptors are entirely optional
136        }
137
138        return new CoreExtensionEntry( loader, artifacts, packages );
139    }
140
141}