1   /*
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   */
19  package org.apache.felix.obrplugin;
20  
21  
22  import java.io.File;
23  import java.net.URI;
24  import java.util.Arrays;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.manager.WagonManager;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.settings.Settings;
33  
34  
35  /**
36   * Deploys bundle details to a remote OBR repository (command-line goal)
37   * 
38   * @requiresProject false
39   * @goal deploy-file
40   * @phase deploy
41   * 
42   * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
43   */
44  public final class ObrDeployFile extends AbstractFileMojo
45  {
46      /**
47       * When true, ignore remote locking.
48       * 
49       * @parameter expression="${ignoreLock}"
50       */
51      private boolean ignoreLock;
52  
53      /**
54       * Remote OBR Repository.
55       * 
56       * @parameter expression="${remoteOBR}"
57       */
58      private String remoteOBR;
59  
60      /**
61       * Local OBR Repository.
62       * 
63       * @parameter expression="${obrRepository}"
64       */
65      private String obrRepository;
66  
67      /**
68       * Project types which this plugin supports.
69       *
70       * @parameter
71       */
72      private List supportedProjectTypes = Arrays.asList( new String[]
73          { "jar", "bundle" } );
74  
75      /**
76       * Remote repository id, used to lookup authentication settings.
77       *
78       * @parameter expression="${repositoryId}" default-value="remote-repository"
79       * @required
80       */
81      private String repositoryId;
82  
83      /**
84       * Remote OBR repository URL, where the bundle details are to be uploaded.
85       *
86       * @parameter expression="${url}"
87       * @required
88       */
89      private String url;
90  
91      /**
92       * Optional public URL where the bundle has been deployed.
93       *
94       * @parameter expression="${bundleUrl}"
95       */
96      private String bundleUrl;
97  
98      /**
99       * Local Repository.
100      * 
101      * @parameter expression="${localRepository}"
102      * @required
103      * @readonly
104      */
105     private ArtifactRepository localRepository;
106 
107     /**
108      * Local Maven settings.
109      * 
110      * @parameter expression="${settings}"
111      * @required
112      * @readonly
113      */
114     private Settings settings;
115 
116     /**
117      * The Wagon manager.
118      * 
119      * @component
120      */
121     private WagonManager m_wagonManager;
122 
123 
124     public void execute() throws MojoExecutionException
125     {
126         MavenProject project = getProject();
127         String projectType = project.getPackaging();
128 
129         // ignore unsupported project types, useful when bundleplugin is configured in parent pom
130         if ( !supportedProjectTypes.contains( projectType ) )
131         {
132             getLog().warn(
133                 "Ignoring project type " + projectType + " - supportedProjectTypes = " + supportedProjectTypes );
134             return;
135         }
136         else if ( "NONE".equalsIgnoreCase( remoteOBR ) || "false".equalsIgnoreCase( remoteOBR ) )
137         {
138             getLog().info( "Remote OBR update disabled (enable with -DremoteOBR)" );
139             return;
140         }
141 
142         // if the user doesn't supply an explicit name for the remote OBR file, use the local name instead
143         if ( null == remoteOBR || remoteOBR.trim().length() == 0 || "true".equalsIgnoreCase( remoteOBR ) )
144         {
145             remoteOBR = obrRepository;
146         }
147 
148         URI tempURI = ObrUtils.findRepositoryXml( "", remoteOBR );
149         String repositoryName = new File( tempURI.getSchemeSpecificPart() ).getName();
150 
151         Log log = getLog();
152         ObrUpdate update;
153 
154         RemoteFileManager remoteFile = new RemoteFileManager( m_wagonManager, settings, log );
155         remoteFile.connect( repositoryId, url );
156 
157         // ======== LOCK REMOTE OBR ========
158         log.info( "LOCK " + remoteFile + '/' + repositoryName );
159         remoteFile.lockFile( repositoryName, ignoreLock );
160         File downloadedRepositoryXml = null;
161 
162         try
163         {
164             // ======== DOWNLOAD REMOTE OBR ========
165             log.info( "Downloading " + repositoryName );
166             downloadedRepositoryXml = remoteFile.get( repositoryName, ".xml" );
167 
168             String mavenRepository = localRepository.getBasedir();
169 
170             URI repositoryXml = downloadedRepositoryXml.toURI();
171             URI obrXmlFile = ObrUtils.toFileURI( obrXml );
172             URI bundleJar;
173 
174             if ( null == file )
175             {
176                 bundleJar = ObrUtils.getArtifactURI( localRepository, project.getArtifact() );
177             }
178             else
179             {
180                 bundleJar = file.toURI();
181             }
182 
183             Config userConfig = new Config();
184             userConfig.setRemoteFile( true );
185 
186             if ( null != bundleUrl )
187             {
188                 // public URL differs from the bundle file location
189                 URI uri = URI.create( bundleUrl );
190                 log.info( "Computed bundle uri: " + uri );
191                 userConfig.setRemoteBundle( uri );
192             }
193             else if ( null != file )
194             {
195                 // assume file will be deployed in remote repository, so find the remote relative location
196                 URI uri = URI.create( localRepository.pathOf( project.getArtifact() ) );
197                 log.info( "Computed bundle uri: " + uri );
198                 userConfig.setRemoteBundle( uri );
199             }
200 
201             update = new ObrUpdate( repositoryXml, obrXmlFile, project, mavenRepository, userConfig, log );
202             update.parseRepositoryXml();
203 
204             update.updateRepository( bundleJar, null, null );
205 
206             update.writeRepositoryXml();
207 
208             if ( downloadedRepositoryXml.exists() )
209             {
210                 // ======== UPLOAD MODIFIED OBR ========
211                 log.info( "Uploading " + repositoryName );
212                 remoteFile.put( downloadedRepositoryXml, repositoryName );
213             }
214         }
215         catch ( Exception e )
216         {
217             log.warn( "Exception while updating remote OBR: " + e.getLocalizedMessage(), e );
218         }
219         finally
220         {
221             // ======== UNLOCK REMOTE OBR ========
222             log.info( "UNLOCK " + remoteFile + '/' + repositoryName );
223             remoteFile.unlockFile( repositoryName );
224             remoteFile.disconnect();
225 
226             if ( null != downloadedRepositoryXml )
227             {
228                 downloadedRepositoryXml.delete();
229             }
230         }
231     }
232 }