View Javadoc
1   package org.apache.maven.scm.provider.bazaar.repository;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
23  import org.codehaus.plexus.util.StringUtils;
24  
25  import java.io.File;
26  
27  /**
28   * @author <a href="mailto:torbjorn@smorgrav.org">Torbj�rn Eikli Sm�rgrav</a>
29   *
30   */
31  public class BazaarScmProviderRepository
32      extends ScmProviderRepositoryWithHost
33  {
34      //Known and tested protocols
35      private static final String FILE = "file://";
36  
37      private static final String SFTP = "sftp://";
38  
39      private static final String FTP = "ftp://";
40  
41      private static final String AFTP = "aftp://";
42  
43      private static final String HTTP = "http://";
44  
45      private static final String HTTPS = "https://";
46  
47      private static final String BZR = "bzr://";
48  
49      private static final String BZR_SSH = "bzr+ssh://";
50  
51      /** this is basically an abbreviation of {@value #BZR_SSH} */
52      private static final String SSH = "ssh://";
53  
54      private static final String UNKNOWN = "";
55  
56      private final String path;
57  
58      private final String protocol;
59  
60      private final String orgUrl;
61  
62      public BazaarScmProviderRepository( String url )
63      {
64          orgUrl = url;
65          protocol = getProtocol( url );
66          path = parseUrl( url );
67      }
68  
69      public String getURI()
70      {
71          if ( FILE.equals( protocol ) )
72          {
73              return orgUrl;
74          }
75          else
76          {
77              return protocol + ( needsAuthentication() ? addUser() + addPassword() + addAt() : "" ) + addHost()
78                  + addPort() + addPath();
79          }
80      }
81  
82      /**
83       * @return A message if the repository as an invalid URI, null if the URI seems fine.
84       */
85      public String validateURI()
86      {
87  
88          String msg = null;
89  
90          if ( UNKNOWN.equals( protocol ) )
91          {
92              msg = "Unknown protocol (URL should start with something like 'sftp://' or 'file://'";
93          }
94          else if ( needsAuthentication() )
95          {
96              if ( getUser() == null )
97              {
98                  msg = "Username is missing for protocol " + protocol;
99              }
100             else if ( getPassword() == null )
101             {
102                 msg = "Password is missing for protocol " + protocol;
103             }
104             else if ( getHost() == null )
105             {
106                 msg = "Host (eg. www.myhost.com) is missing for protocol " + protocol;
107             }
108         }
109 
110         else if ( getPort() != 0 && getHost() == null )
111         {
112             msg = "Got port information without any host for protocol " + protocol;
113         }
114 
115         if ( msg != null )
116         {
117             msg = "Something could be wrong about the repository URL: " + orgUrl + "\nReason: " + msg
118                 + "\nCheck http://maven.apache.org/scm for usage and hints.";
119         }
120         return msg;
121     }
122 
123     private String getProtocol( String url )
124     {
125         String prot = UNKNOWN;
126         if ( url.startsWith( FILE ) )
127         {
128             prot = FILE;
129         }
130         else if ( url.startsWith( FTP ) )
131         {
132             prot = FTP;
133         }
134         else if ( url.startsWith( SFTP ) )
135         {
136             prot = SFTP;
137         }
138         else if ( url.startsWith( AFTP ) )
139         {
140             prot = AFTP;
141         }
142         else if ( url.startsWith( HTTP ) )
143         {
144             prot = HTTP;
145         }
146         else if ( url.startsWith( HTTPS ) )
147         {
148             prot = HTTPS;
149         }
150         else if ( url.startsWith( BZR ) )
151         {
152             prot = BZR;
153         }
154         else if ( url.startsWith( BZR_SSH ) )
155         {
156             prot = BZR_SSH;
157         }
158         else if ( url.startsWith( SSH ) )
159         {
160             prot = SSH;
161         }
162 
163         return prot;
164     }
165 
166     private String parseUrl( String url )
167     {
168         if ( UNKNOWN.equals( protocol ) )
169         {
170             return url;
171         }
172 
173         //Strip protocol
174         url = url.substring( protocol.length() );
175 
176         url = parseUsernameAndPassword( url );
177 
178         url = parseHostAndPort( url );
179 
180         url = parsePath( url );
181 
182         return url; //is now only the path
183     }
184 
185     private String parseHostAndPort( String url )
186     {
187         if ( !FILE.equals( protocol ) )
188         {
189             int indexSlash = url.indexOf( '/' );
190 
191             String hostPort = url;
192             if ( indexSlash > 0 )
193             {
194                 hostPort = url.substring( 0, indexSlash );
195             }
196 
197             int indexColon = hostPort.indexOf( ':' );
198             if ( indexColon > 0 )
199             {
200                 setHost( hostPort.substring( 0, indexColon ) );
201                 url = StringUtils.replace( url, getHost(), "" );
202                 setPort( Integer.parseInt( hostPort.substring( indexColon + 1 ) ) );
203                 url = StringUtils.replace( url, ":" + getPort(), "" );
204             }
205             else
206             {
207                 setHost( hostPort );
208                 url = StringUtils.replace( url, getHost(), "" );
209             }
210         }
211 
212         return url;
213     }
214 
215     private String parseUsernameAndPassword( String url )
216     {
217         if ( needsAuthentication() )
218         {
219             String[] split = url.split( "@" );
220             if ( split.length == 2 )
221             {
222                 url = split[1]; //Strip away 'username:password@' from url
223                 split = split[0].split( ":" );
224                 if ( split.length == 2 )
225                 { //both username and password
226                     setUser( split[0] );
227                     setPassword( split[1] );
228                 }
229                 else
230                 { //only username
231                     setUser( split[0] );
232                 }
233             }
234         }
235         return url;
236     }
237 
238     private String parsePath( String url )
239     {
240         if ( FILE.equals( protocol ) )
241         {
242             //Use OS dependent path separator
243             url = StringUtils.replace( url, "/", File.separator );
244 
245             //Test first path separator (*nix systems use them to denote root)
246             File tmpFile = new File( url ); //most likly a *nix system
247             String url2 = url.substring( File.pathSeparator.length() );
248             File tmpFile2 = new File( url2 ); //most likly a windows system
249             if ( !tmpFile.exists() && !tmpFile2.exists() )
250             {
251                 // This is trouble - Trouble is reported in validateURI()
252             }
253 
254             url = tmpFile2.exists() ? url2 : url;
255 
256             //Use URL path separator
257             url = StringUtils.replace( url, File.separator, "/" );
258         }
259 
260         return url;
261     }
262 
263     private String addUser()
264     {
265         return ( getUser() == null ) ? "" : getUser();
266     }
267 
268     private String addPassword()
269     {
270         return ( getPassword() == null ) ? "" : ":" + getPassword();
271     }
272 
273     private String addAt()
274     {
275         return needsAuthentication() ? "@" : "";
276     }
277 
278     private String addHost()
279     {
280         return ( getHost() == null ) ? "" : getHost();
281     }
282 
283     private String addPort()
284     {
285         return ( getPort() == 0 ) ? "" : ":" + getPort();
286     }
287 
288     private String addPath()
289     {
290         return path;
291     }
292 
293     private boolean needsAuthentication()
294     {
295         return SFTP.equals( protocol ) || 
296                FTP.equals( protocol ) || 
297                HTTPS.equals( protocol ) || 
298                AFTP.equals( protocol ) ||
299                BZR.equals( protocol ) ||
300                BZR_SSH.equals( protocol ) ||
301                SSH.equals( protocol );
302     }
303 
304     /** {@inheritDoc} */
305     public String toString()
306     {
307         return "Bazaar Repository Interpreted from: " + orgUrl + ":\nProtocol: " + protocol + "\nHost: "
308             + getHost() + "\nPort: " + getPort() + "\nUsername: " + getUser() + "\nPassword: " + getPassword()
309             + "\nPath: " + path;
310     }
311 }