001    /*
002     *  Copyright 2005 The Apache Software Foundation
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.apache.geronimo.plugin.car;
018    
019    import org.apache.geronimo.kernel.config.InvalidConfigException;
020    import org.apache.geronimo.kernel.config.NoSuchConfigException;
021    import org.apache.geronimo.kernel.config.ConfigurationData;
022    import org.apache.geronimo.kernel.repository.Artifact;
023    import org.apache.geronimo.kernel.repository.ArtifactManager;
024    import org.apache.geronimo.kernel.repository.ArtifactResolver;
025    import org.apache.geronimo.kernel.repository.DefaultArtifactManager;
026    import org.apache.geronimo.kernel.repository.Environment;
027    import org.apache.geronimo.kernel.repository.FileWriteMonitor;
028    import org.apache.geronimo.kernel.repository.MissingDependencyException;
029    import org.apache.geronimo.kernel.repository.Dependency;
030    import org.apache.geronimo.kernel.repository.WritableListableRepository;
031    import org.apache.geronimo.system.repository.Maven2Repository;
032    import org.apache.geronimo.system.configuration.RepositoryConfigurationStore;
033    import org.apache.geronimo.system.resolver.ExplicitDefaultArtifactResolver;
034    
035    import org.apache.geronimo.plugin.MojoSupport;
036    
037    import org.apache.maven.artifact.repository.ArtifactRepository;
038    import org.apache.maven.project.MavenProject;
039    import org.apache.maven.plugin.MojoExecutionException;
040    
041    import java.io.File;
042    import java.io.FileInputStream;
043    import java.io.IOException;
044    import java.io.InputStream;
045    
046    import java.util.Iterator;
047    import java.util.HashSet;
048    import java.util.LinkedHashSet;
049    import java.util.Set;
050    import java.util.Collections;
051    
052    /**
053     * Installs CAR files into a target repository to support assembly.
054     *
055     * @goal installConfig
056     * 
057     * @version $Rev: 428888 $ $Date: 2006-08-04 23:21:54 +0200 (ven., 04 août 2006) $
058     */
059    public class InstallConfigMojo
060        extends AbstractCarMojo
061    {
062        public static final FileWriteMonitor LOG_COPY_START = new StartFileWriteMonitor();
063    
064        /**
065         * Root file of the TargetRepository.
066         *
067         * @parameter expression="${project.build.directory}"
068         */
069        private String targetRoot;
070    
071        /**
072         * The location of the target repository relative to targetRoot.
073         * 
074         * @parameter default-value="archive-tmp/repository"
075         * @required
076         */
077        private String targetRepository;
078    
079        /**
080         * Configuration to be installed specified as groupId/artifactId/version/type
081         * if none specified, plugin will install all dependencies of type "car"
082         *
083         * @parameter
084         * @optional
085         */
086        private String artifact;
087    
088        /**
089         * Location of the source repository for the dependencies
090         *
091         * @parameter expression="${localRepository}"
092         * @required
093         */
094        private ArtifactRepository sourceRepository;
095        
096        /**
097         * The location where the properties mapping will be generated.
098         *
099         * @parameter expression="${project.build.directory}/explicit-versions.properties"
100         * @required
101         */
102        private File explicitResolutionProperties;
103    
104        private ArtifactResolver artifactResolver;
105    
106        private WritableListableRepository targetRepo;
107        private RepositoryConfigurationStore targetStore;
108    
109        private WritableListableRepository sourceRepo;
110        private RepositoryConfigurationStore sourceStore;
111    
112        protected void doExecute() throws Exception {
113            generateExplicitVersionProperties(explicitResolutionProperties);
114            
115            sourceRepo = new Maven2Repository(new File(sourceRepository.getBasedir()));
116            sourceStore = new RepositoryConfigurationStore(sourceRepo);
117    
118            File targetRepoFile = new File(targetRoot, targetRepository);
119            if (!targetRepoFile.exists()) {
120                targetRepoFile.mkdirs();
121            }
122            
123            targetRepo = new Maven2Repository(targetRepoFile);
124            targetStore = new RepositoryConfigurationStore(targetRepo);
125    
126            Artifact configId;
127            ArtifactManager artifactManager = new DefaultArtifactManager();
128            artifactResolver = new ExplicitDefaultArtifactResolver(
129                explicitResolutionProperties.getPath(),
130                artifactManager,
131                Collections.singleton(sourceRepo),
132                null);
133    
134            if ( artifact != null ) {
135                configId = Artifact.create(artifact);
136                execute(configId);
137            }
138            else {
139                Iterator itr = getDependencies().iterator();
140                while (itr.hasNext()) {
141                    org.apache.maven.artifact.Artifact mavenArtifact = (org.apache.maven.artifact.Artifact) itr.next();
142                    if ("car".equals(mavenArtifact.getType())) {
143                        configId = new Artifact(mavenArtifact.getGroupId(), mavenArtifact.getArtifactId(), mavenArtifact.getVersion(), "car");
144                        execute(configId);
145                    }
146                }
147            }
148        }
149    
150        /**
151         * Retrieves all artifact dependencies.
152         *
153         * @return A HashSet of artifacts
154         */
155        protected Set getDependencies() {
156            Set dependenciesSet = new HashSet();
157    
158            if (project.getArtifact() != null && project.getArtifact().getFile() != null) {
159                dependenciesSet.add( project.getArtifact() );
160            }
161    
162            Set projectArtifacts = project.getArtifacts();
163            if (projectArtifacts != null) {
164                dependenciesSet.addAll(projectArtifacts);
165            }
166    
167            return dependenciesSet;
168        }
169    
170        private void execute(Artifact configId) throws Exception {
171            LinkedHashSet dependencies;
172    
173            // does this configuration exist?
174            if (!sourceRepo.contains(configId)) {
175                throw new NoSuchConfigException(configId);
176            }
177    
178            // is this config already installed?
179            if (targetStore.containsConfiguration(configId)) {
180                log.info("Configuration " + configId + " already present in configuration store");
181                return;
182            }
183    
184            if (sourceStore.containsConfiguration(configId)) {
185                // Copy the configuration into the target configuration store
186                if (!targetStore.containsConfiguration(configId)) {
187                    File sourceFile = sourceRepo.getLocation(configId);
188                    InputStream in = new FileInputStream(sourceFile);
189                    try {
190                        targetStore.install(in, (int)sourceFile.length(), configId, LOG_COPY_START);
191                    }
192                    finally {
193                        in.close();
194                    }
195                }
196    
197                // Determine the dependencies of this configuration
198                try {
199                    ConfigurationData configurationData = targetStore.loadConfiguration(configId);
200                    Environment environment = configurationData.getEnvironment();
201                    dependencies = new LinkedHashSet();
202                    for (Iterator iterator = environment.getDependencies().iterator(); iterator.hasNext();) {
203                        Dependency dependency = (Dependency) iterator.next();
204                        dependencies.add(dependency.getArtifact());
205                    }
206    
207                    log.info("Installed configuration " + configId);
208                }
209                catch (IOException e) {
210                    throw new InvalidConfigException("Unable to load configuration: " + configId, e);
211                }
212                catch (NoSuchConfigException e) {
213                    throw new InvalidConfigException("Unable to load configuration: " + configId, e);
214                }
215            }
216            else {
217                if (!sourceRepo.contains(configId)) {
218                    throw new RuntimeException("Dependency: " + configId + " not found in local maven repo: for configuration: " + artifact);
219                }
220    
221                // Copy the artifact into the target repo
222                if (!targetRepo.contains(configId)) {
223                    File sourceFile = sourceRepo.getLocation(configId);
224                    InputStream in = new FileInputStream(sourceFile);
225                    try {
226                        targetRepo.copyToRepository(in, (int)sourceFile.length(), configId, LOG_COPY_START);
227                    }
228                    finally {
229                        in.close();
230                    }
231                }
232    
233                // Determine the dependencies of this artifact
234                dependencies = sourceRepo.getDependencies(configId);
235            }
236            
237            dependencies = artifactResolver.resolveInClassLoader(dependencies);
238            for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) {
239                Artifact artifact = (Artifact) iterator.next();
240                execute(artifact);
241            }
242        }
243    
244        private static class StartFileWriteMonitor implements FileWriteMonitor {
245            public void writeStarted(String fileDescription, int fileSize) {
246                //
247                // FIXME: Using logging?
248                //
249                
250                System.out.println("Copying " + fileDescription);
251            }
252    
253            public void writeProgress(int bytes) {
254                // ???
255            }
256    
257            public void writeComplete(int bytes) {
258                // ???
259            }
260        }
261    }