blob: bf25f00d6aa9ba5e9a12ab8a33f49e9584a46c70 [file] [log] [blame]
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Stuart McCullochc792b372008-02-17 16:12:24 +000019package org.apache.felix.obrplugin;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000020
21
22import java.io.File;
23import java.net.URI;
Stuart McCulloch69ab1132008-08-02 18:47:46 +000024import java.net.URL;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000025import java.util.Arrays;
Stuart McCullochd04364c2008-02-18 17:23:11 +000026import java.util.Iterator;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000027import java.util.List;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30
Stuart McCullochd04364c2008-02-18 17:23:11 +000031import org.apache.maven.artifact.Artifact;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000032import org.apache.maven.artifact.manager.WagonManager;
33import org.apache.maven.artifact.repository.ArtifactRepository;
34import org.apache.maven.plugin.AbstractMojo;
35import org.apache.maven.plugin.MojoExecutionException;
36import org.apache.maven.plugin.logging.Log;
37import org.apache.maven.project.MavenProject;
38import org.apache.maven.settings.Settings;
39
40
41/**
42 * Deploys bundle details to a remote OBR repository (life-cycle goal)
43 *
44 * @goal deploy
45 * @phase deploy
46 *
47 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
48 */
49public final class ObrDeploy extends AbstractMojo
50{
51 /**
52 * When true, ignore remote locking.
53 *
54 * @parameter expression="${ignoreLock}"
55 */
56 private boolean ignoreLock;
57
58 /**
Stuart McCulloch69ab1132008-08-02 18:47:46 +000059 * Optional public URL prefix for the remote repository.
60 *
61 * @parameter expression="${prefixUrl}"
62 */
63 private String prefixUrl;
64
65 /**
66 * Optional public URL where the bundle has been deployed.
67 *
68 * @parameter expression="${bundleUrl}"
69 */
70 private String bundleUrl;
71
72 /**
Stuart McCulloch5d6cb732008-02-18 05:24:46 +000073 * Remote OBR Repository.
74 *
75 * @parameter expression="${remoteOBR}" default-value="NONE"
76 */
77 private String remoteOBR;
78
79 /**
80 * Local OBR Repository.
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000081 *
82 * @parameter expression="${obrRepository}"
83 */
84 private String obrRepository;
85
86 /**
87 * Project types which this plugin supports.
88 *
89 * @parameter
90 */
91 private List supportedProjectTypes = Arrays.asList( new String[]
Stuart McCulloch4fd62392008-05-15 16:15:15 +000092 { "jar", "bundle" } );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +000093
94 /**
95 * @parameter expression="${project.distributionManagementArtifactRepository}"
96 * @readonly
97 */
98 private ArtifactRepository deploymentRepository;
99
100 /**
101 * Alternative deployment repository. Format: id::layout::url
102 *
103 * @parameter expression="${altDeploymentRepository}"
104 */
105 private String altDeploymentRepository;
106
107 /**
Stuart McCulloch69ab1132008-08-02 18:47:46 +0000108 * OBR specific deployment repository. Format: id::layout::url
109 *
110 * @parameter expression="${obrDeploymentRepository}"
111 */
112 private String obrDeploymentRepository;
113
114 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000115 * Local Repository.
116 *
117 * @parameter expression="${localRepository}"
118 * @required
119 * @readonly
120 */
121 private ArtifactRepository localRepository;
122
123 /**
124 * The Maven project.
125 *
126 * @parameter expression="${project}"
127 * @required
128 * @readonly
129 */
130 private MavenProject project;
131
132 /**
Stuart McCullochd04364c2008-02-18 17:23:11 +0000133 * @parameter expression="${project.attachedArtifacts}
134 * @required
135 * @readonly
136 */
137 private List attachedArtifacts;
138
139 /**
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000140 * Local Maven settings.
141 *
142 * @parameter expression="${settings}"
143 * @required
144 * @readonly
145 */
146 private Settings settings;
147
148 /**
149 * The Wagon manager.
150 *
151 * @component
152 */
153 private WagonManager m_wagonManager;
154
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000155 /**
156 * Attached source artifact
157 */
158 private Artifact m_sourceArtifact;
159
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000160 /**
161 * Attached doc artifact
162 */
163 private Artifact m_docArtifact;
164
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000165
166 public void execute() throws MojoExecutionException
167 {
Stuart McCulloch3a965b92008-03-24 02:34:11 +0000168 String projectType = project.getPackaging();
169
170 // ignore unsupported project types, useful when bundleplugin is configured in parent pom
171 if ( !supportedProjectTypes.contains( projectType ) )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000172 {
Stuart McCulloch3a965b92008-03-24 02:34:11 +0000173 getLog().warn( "Ignoring project type " + projectType +
174 " - supportedProjectTypes = " + supportedProjectTypes );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000175 return;
176 }
Stuart McCulloch5d6cb732008-02-18 05:24:46 +0000177 else if ( "NONE".equalsIgnoreCase( remoteOBR ) || "false".equalsIgnoreCase( remoteOBR ) )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000178 {
Stuart McCulloch5d6cb732008-02-18 05:24:46 +0000179 getLog().info( "Remote OBR update disabled (enable with -DremoteOBR)" );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000180 return;
181 }
182
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000183 // check for any attached sources or docs
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000184 for ( Iterator i = attachedArtifacts.iterator(); i.hasNext(); )
185 {
186 Artifact artifact = ( Artifact ) i.next();
187 if ( "sources".equals( artifact.getClassifier() ) )
188 {
189 m_sourceArtifact = artifact;
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000190 }
191 else if ( "javadoc".equals( artifact.getClassifier() ) )
192 {
193 m_docArtifact = artifact;
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000194 }
195 }
196
Stuart McCulloch5d6cb732008-02-18 05:24:46 +0000197 // if the user doesn't supply an explicit name for the remote OBR file, use the local name instead
198 if ( null == remoteOBR || remoteOBR.trim().length() == 0 || "true".equalsIgnoreCase( remoteOBR ) )
199 {
200 remoteOBR = obrRepository;
201 }
202
203 URI tempURI = ObrUtils.findRepositoryXml( "", remoteOBR );
Stuart McCulloch435f3902008-08-02 16:50:31 +0000204 String repositoryName = new File( tempURI.getSchemeSpecificPart() ).getName();
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000205
206 Log log = getLog();
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000207 ObrUpdate update;
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000208
209 RemoteFileManager remoteFile = new RemoteFileManager( m_wagonManager, settings, log );
210 openRepositoryConnection( remoteFile );
211
212 // ======== LOCK REMOTE OBR ========
213 log.info( "LOCK " + remoteFile + '/' + repositoryName );
214 remoteFile.lockFile( repositoryName, ignoreLock );
215 File downloadedRepositoryXml = null;
216
217 try
218 {
219 // ======== DOWNLOAD REMOTE OBR ========
220 log.info( "Downloading " + repositoryName );
221 downloadedRepositoryXml = remoteFile.get( repositoryName, ".xml" );
222
223 String mavenRepository = localRepository.getBasedir();
224
225 URI repositoryXml = downloadedRepositoryXml.toURI();
226 URI obrXmlFile = ObrUtils.findObrXml( project.getResources() );
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000227
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000228 Config userConfig = new Config();
229 userConfig.setRemoteFile( true );
Stuart McCulloch69ab1132008-08-02 18:47:46 +0000230
231 if ( bundleUrl != null )
232 {
233 // public URL differs from the bundle file location
234 userConfig.setRemoteBundle( URI.create( bundleUrl ) );
235 }
236 else if ( prefixUrl != null )
237 {
238 // support absolute bundle URLs based on given prefix
239 URI bundleJar = ObrUtils.getArtifactURI( localRepository, project.getArtifact() );
240 String relative = ObrUtils.getRelativeURI( ObrUtils.toFileURI( mavenRepository ), bundleJar).toASCIIString();
241 URL resourceURL = new URL( new URL( prefixUrl + '/' ), relative );
Stuart McCullochb7235e32008-08-03 09:41:43 +0000242 userConfig.setRemoteBundle( URI.create( resourceURL.toString() ) );
Stuart McCulloch69ab1132008-08-02 18:47:46 +0000243 }
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000244
245 update = new ObrUpdate( repositoryXml, obrXmlFile, project, mavenRepository, userConfig, log );
246 update.parseRepositoryXml();
247
248 updateRemoteBundleMetadata( project.getArtifact(), update );
Stuart McCullochd04364c2008-02-18 17:23:11 +0000249 for ( Iterator i = attachedArtifacts.iterator(); i.hasNext(); )
250 {
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000251 updateRemoteBundleMetadata( ( Artifact ) i.next(), update );
Stuart McCullochd04364c2008-02-18 17:23:11 +0000252 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000253
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000254 update.writeRepositoryXml();
255
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000256 if ( downloadedRepositoryXml.exists() )
257 {
258 // ======== UPLOAD MODIFIED OBR ========
259 log.info( "Uploading " + repositoryName );
260 remoteFile.put( downloadedRepositoryXml, repositoryName );
261 }
262 }
263 catch ( Exception e )
264 {
265 log.warn( "Exception while updating remote OBR: " + e.getLocalizedMessage(), e );
266 }
267 finally
268 {
269 // ======== UNLOCK REMOTE OBR ========
270 log.info( "UNLOCK " + remoteFile + '/' + repositoryName );
271 remoteFile.unlockFile( repositoryName );
272 remoteFile.disconnect();
273
274 if ( null != downloadedRepositoryXml )
275 {
276 downloadedRepositoryXml.delete();
277 }
278 }
279 }
280
281 private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" );
282
283
284 private void openRepositoryConnection( RemoteFileManager remoteFile ) throws MojoExecutionException
285 {
Stuart McCulloch69ab1132008-08-02 18:47:46 +0000286 // use OBR specific deployment location?
287 if ( obrDeploymentRepository != null )
288 {
289 altDeploymentRepository = obrDeploymentRepository;
290 }
291
Clement Escoffier78c9efb2008-05-29 16:20:08 +0000292 if ( deploymentRepository == null && altDeploymentRepository == null )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000293 {
294 String msg = "Deployment failed: repository element was not specified in the pom inside"
Clement Escoffier78c9efb2008-05-29 16:20:08 +0000295 + " distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter";
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000296
297 throw new MojoExecutionException( msg );
298 }
299
Clement Escoffier78c9efb2008-05-29 16:20:08 +0000300 if ( altDeploymentRepository != null )
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000301 {
302 getLog().info( "Using alternate deployment repository " + altDeploymentRepository );
303
304 Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( altDeploymentRepository );
305 if ( !matcher.matches() )
306 {
307 throw new MojoExecutionException( "Invalid syntax for alternative repository \""
308 + altDeploymentRepository + "\". Use \"id::layout::url\"." );
309 }
310
311 remoteFile.connect( matcher.group( 1 ).trim(), matcher.group( 3 ).trim() );
312 }
313 else
314 {
315 remoteFile.connect( deploymentRepository.getId(), deploymentRepository.getUrl() );
316 }
317 }
Stuart McCullochd04364c2008-02-18 17:23:11 +0000318
319
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000320 private void updateRemoteBundleMetadata( Artifact artifact, ObrUpdate update ) throws MojoExecutionException
Stuart McCullochd04364c2008-02-18 17:23:11 +0000321 {
Stuart McCulloch4fd62392008-05-15 16:15:15 +0000322 if ( !supportedProjectTypes.contains( artifact.getType() ) )
Stuart McCullochd04364c2008-02-18 17:23:11 +0000323 {
324 return;
325 }
Stuart McCulloch229f0162008-04-23 13:52:42 +0000326 else if ( null == artifact.getFile() || artifact.getFile().isDirectory() )
327 {
328 getLog().error( "No artifact found, try \"mvn install bundle:deploy\"" );
329 return;
330 }
Stuart McCullochd04364c2008-02-18 17:23:11 +0000331
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000332 URI bundleJar = ObrUtils.getArtifactURI( localRepository, artifact );
Stuart McCullochd04364c2008-02-18 17:23:11 +0000333
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000334 URI sourceJar = null;
Stuart McCulloch0ae86ab2008-02-19 06:24:30 +0000335 if ( null != m_sourceArtifact )
336 {
337 sourceJar = ObrUtils.getArtifactURI( localRepository, m_sourceArtifact );
338 }
Stuart McCullochd04364c2008-02-18 17:23:11 +0000339
Stuart McCullocha1d3a292008-02-20 00:53:52 +0000340 URI docJar = null;
341 if ( null != m_docArtifact )
342 {
343 docJar = ObrUtils.getArtifactURI( localRepository, m_docArtifact );
344 }
345
346 update.updateRepository( bundleJar, sourceJar, docJar );
Stuart McCullochd04364c2008-02-18 17:23:11 +0000347 }
Stuart McCullochbb8b9fa2008-02-17 16:07:14 +0000348}