001    /*
002     * Copyright (C) 2006-2007 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.codehaus.gmaven.plugin;
018    
019    import org.apache.maven.artifact.Artifact;
020    import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
021    import org.apache.maven.artifact.resolver.ArtifactResolutionException;
022    import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
023    import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
024    import org.apache.maven.artifact.versioning.VersionRange;
025    import org.apache.commons.lang.SystemUtils;
026    import org.codehaus.gmaven.feature.Provider;
027    import org.codehaus.gmaven.feature.ProviderException;
028    import org.codehaus.gmaven.feature.ProviderManager;
029    import org.codehaus.gmaven.runtime.loader.artifact.ArtifactHandler;
030    import org.codehaus.gmaven.runtime.loader.artifact.ArtifactProviderLoader;
031    
032    import java.util.Collections;
033    import java.util.Map;
034    
035    /**
036     * Provides support for Mojo implementations which need to have access to a {@link Provider} instances.
037     *
038     * @version $Id: ProviderMojoSupport.java 11 2009-07-16 09:25:38Z user57 $
039     * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
040     */
041    public abstract class ProviderMojoSupport
042        extends MojoSupport
043    {
044        /**
045         * @component
046         * @required
047         * @readonly
048         *
049         * @noinspection UnusedDeclaration
050         */
051        private ProviderManager providerManager;
052    
053        /**
054         * A comma-seperated list of provider keys, in order of preference of selection.
055         *
056         * If the invoking JVM is at least Java 1.5, then the Groovy 1.6 runtime will be used, else
057         * the Groovy 1.5 runtime is used.
058         *
059         * @parameter expression="${gmaven.runtime}"
060         *
061         * @noinspection UnusedDeclaration
062         */
063        private String providerSelection = detectCompatibleProvider();
064    
065        /**
066         * @component role="org.codehaus.gmaven.feature.ProviderLoader" role-hint="artifact"
067         * @required
068         * @readonly
069         * 
070         * @noinspection UnusedDeclaration
071         */
072        private ArtifactProviderLoader artifactProviderLoader;
073    
074        private ArtifactHandler artifactHandler;
075    
076        private void configureArtifactProviderLoader() {
077            if (artifactHandler == null) {
078                try {
079                    assert artifactProviderLoader != null;
080                    artifactProviderLoader.setHandler(new ArtifactHandlerImpl());
081                    artifactHandler = artifactProviderLoader.getHandler();
082    
083                    log.debug("Artifact loader configured with handler: {}", artifactHandler);
084                }
085                catch (Throwable t) {
086                    log.error("Failed to configure the artifact loader: " + t, t);
087                }
088            }
089        }
090    
091        protected ProviderManager getProviderManager() {
092            configureArtifactProviderLoader();
093    
094            return providerManager;
095        }
096    
097        protected String detectCompatibleProvider() {
098            String provider;
099    
100            if (SystemUtils.isJavaVersionAtLeast(1.5f)) {
101                provider = "1.6";
102            }
103            else {
104                provider = "1.5";
105            }
106    
107            log.debug("Detected compatible provider: {}", provider);
108            
109            return provider;
110        }
111    
112        protected String getProviderSelection() {
113            return providerSelection;
114        }
115    
116        private Provider selectedProvider;
117    
118        protected Provider provider() throws Exception {
119            if (selectedProvider == null) {
120                selectedProvider = getProviderManager().select(getProviderSelection());
121            }
122            
123            return selectedProvider;
124        }
125    
126        /**
127         * @parameter expression="${plugin.artifactMap}"
128         * @required
129         * @readonly
130         *
131         * @noinspection UnusedDeclaration,MismatchedQueryAndUpdateOfCollection
132         */
133        protected Map pluginArtifactMap;
134    
135        //
136        // ArtifactHandlerImpl
137        //
138        
139        private class ArtifactHandlerImpl
140            implements ArtifactHandler
141        {
142            // private final Logger log = LoggerFactory.getLogger(getClass());
143    
144            private final Artifact template;
145    
146            private final Artifact originating;
147    
148            public ArtifactHandlerImpl() throws Exception {
149                String id = "org.codehaus.gmaven.runtime:gmaven-runtime-loader";
150    
151                Artifact base = (Artifact) pluginArtifactMap.get(id);
152    
153                if (base == null) {
154                    throw new ProviderException("Missing dependency in the list of plugin artifacts: " + id);
155                }
156    
157                this.template = artifactFactory.createArtifact("org.codehaus.gmaven.runtime", "gmaven-runtime-", base.getBaseVersion(), base.getScope(), base.getType());
158    
159                // This is a synthetic artifact, using a reasonable sounding name to avoid confusing users about the dummy artifact
160                this.originating = artifactFactory.createBuildArtifact("org.codehaus.gmaven.runtime", "gmaven-runtime-loader-stub", base.getBaseVersion(), "jar");
161            }
162    
163            public Artifact createQuery(final String key) {
164                assert key != null;
165    
166                return artifactFactory.createArtifact(
167                        template.getGroupId(),
168                        template.getArtifactId() + key,
169                        template.getVersion(),
170                        template.getScope(),
171                        template.getType());
172            }
173    
174            public Artifact createDependency(final Artifact query) {
175                assert query != null;
176    
177                return artifactFactory.createDependencyArtifact(
178                        query.getGroupId(),
179                        query.getArtifactId(),
180                        VersionRange.createFromVersion(query.getVersion()),
181                        "jar",
182                        null,
183                        Artifact.SCOPE_RUNTIME);
184            }
185    
186            public ArtifactResolutionResult resolve(final Artifact artifact, final ArtifactFilter filter) throws ArtifactNotFoundException, ArtifactResolutionException {
187                assert artifact != null;
188    
189                ArtifactFilter filters = new ArtifactFilter() {
190                    public boolean include(final Artifact artifact) {
191                        assert artifact != null;
192                        
193                        boolean include = false;
194    
195                        if (filter != null) {
196                            include = filter.include(artifact);
197                        }
198    
199                        if (include) {
200                            include = !pluginArtifactMap.containsKey(artifact.getGroupId() + ":" + artifact.getArtifactId());
201                        }
202    
203                        return include;
204                    }
205                };
206    
207                return artifactResolver.resolveTransitively(
208                        Collections.singleton(artifact),
209                        originating,
210                        artifactRepository,
211                        remoteRepositories,
212                        artifactMetadataSource,
213                        filters);
214            }
215        }
216    }