View Javadoc
1   package org.apache.maven.scm.provider.hg.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:thurner.rupert@ymono.net">thurner rupert</a>
29   *
30   */
31  public class HgScmProviderRepository
32      extends ScmProviderRepositoryWithHost
33  {
34      //Known and tested protocols
35      private static final String 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 final String path;
48  
49      private final String protocol;
50  
51      private final String orgUrl;
52  
53      public HgScmProviderRepository( String url )
54      {
55          orgUrl = url;
56          protocol = getProtocol( url );
57          path = parseUrl( url );
58      }
59  
60      public String getURI()
61      {
62          return protocol + addAuthority() + addHost() + addPort() + addPath();
63      }
64  
65      /**
66       * @return A message if the repository as an invalid URI, null if the URI seems fine.
67       */
68      public String validateURI()
69      {
70  
71          String msg = null;
72  
73          if ( needsAuthentication() )
74          {
75              if ( getUser() == null )
76              {
77                  msg = "Username is missing for protocol " + protocol;
78              }
79              else if ( getPassword() == null )
80              {
81                  msg = "Password is missing for protocol " + protocol;
82              }
83              else if ( getHost() == null )
84              {
85                  msg = "Host (eg. www.myhost.com) is missing for protocol " + protocol;
86              }
87          }
88  
89          else if ( getPort() != 0 && getHost() == null )
90          {
91              msg = "Got port information without any host for protocol " + protocol;
92          }
93  
94          if ( msg != null )
95          {
96              msg =
97                  "Something could be wrong about the repository URL: " + orgUrl + "\nReason: " + msg
98                      + "\nCheck http://maven.apache.org/scm for usage and hints.";
99          }
100         return msg;
101     }
102 
103     private String getProtocol( String url )
104     {
105         // Assume we have a file unless we find a URL based syntax
106         String prot = FILE;
107         if ( url.startsWith( SFTP ) )
108         {
109             prot = SFTP;
110         }
111         else if ( url.startsWith( HTTP ) )
112         {
113             prot = HTTP;
114         }
115         else if ( url.startsWith( HTTPS ) )
116         {
117             prot = HTTPS;
118         }
119 
120         return prot;
121     }
122 
123     private String parseUrl( String url )
124     {
125         if ( protocol == FILE )
126         {
127             return url;
128         }
129 
130         //Strip protocol
131         url = url.substring( protocol.length() );
132 
133         url = parseUsernameAndPassword( url );
134 
135         url = parseHostAndPort( url );
136 
137         url = parsePath( url );
138 
139         return url; //is now only the path
140     }
141 
142     private String parseHostAndPort( String url )
143     {
144         if ( protocol != FILE )
145         {
146             int indexSlash = url.indexOf( '/' );
147 
148             String hostPort = url;
149             if ( indexSlash > 0 )
150             {
151                 hostPort = url.substring( 0, indexSlash );
152                 url = url.substring( indexSlash );
153             }
154 
155             int indexColon = hostPort.indexOf( ':' );
156             if ( indexColon > 0 )
157             {
158                 setHost( hostPort.substring( 0, indexColon ) );
159                 setPort( Integer.parseInt( hostPort.substring( indexColon + 1 ) ) );
160             }
161             else
162             {
163                 setHost( hostPort );
164             }
165         }
166 
167         return url;
168     }
169 
170     private String parseUsernameAndPassword( String url )
171     {
172         if ( canAuthenticate() )
173         {
174             String[] split = url.split( "@" );
175             if ( split.length == 2 )
176             {
177                 url = split[1]; //Strip away 'username:password@' from url
178                 split = split[0].split( ":" );
179                 if ( split.length == 2 )
180                 { //both username and password
181                     setUser( split[0] );
182                     setPassword( split[1] );
183                 }
184                 else
185                 { //only username
186                     setUser( split[0] );
187                 }
188             }
189         }
190         return url;
191     }
192 
193     private String parsePath( String url )
194     {
195         if ( protocol == FILE )
196         {
197             //Use OS dependent path separator
198             url = StringUtils.replace( url, "/", File.separator );
199 
200             //Test first path separator (*nix systems use them to denote root)
201             File tmpFile = new File( url ); //most likly a *nix system
202             String url2 = url.substring( File.pathSeparator.length() );
203             File tmpFile2 = new File( url2 ); //most likly a windows system
204             if ( !tmpFile.exists() && !tmpFile2.exists() )
205             {
206                 // This is trouble - Trouble is reported in validateURI()
207             }
208 
209             url = tmpFile2.exists() ? url2 : url;
210         }
211 
212         return url;
213     }
214 
215     private String addUser()
216     {
217         return ( getUser() == null ) ? "" : getUser();
218     }
219 
220     private String addPassword()
221     {
222         return ( getPassword() == null ) ? "" : ":" + getPassword();
223     }
224 
225     private String addHost()
226     {
227         return ( getHost() == null ) ? "" : getHost();
228     }
229 
230     private String addPort()
231     {
232         return ( getPort() == 0 ) ? "" : ":" + getPort();
233     }
234 
235     private String addPath()
236     {
237         return path;
238     }
239 
240     private boolean needsAuthentication()
241     {
242         return protocol == SFTP || protocol == FTP || protocol == HTTPS || protocol == AFTP;
243     }
244 
245     private String addAuthority()
246     {
247         return ( ( canAuthenticate() && ( getUser() != null ) ) ? addUser() + addPassword() + "@" : "" );
248     }
249 
250 
251     private boolean canAuthenticate()
252     {
253         return needsAuthentication() || protocol == HTTP;
254     }
255     /** {@inheritDoc} */
256     public String toString()
257     {
258         return "Hg Repository Interpreted from: " + orgUrl + ":\nProtocol: " + protocol + "\nHost: " + getHost()
259             + "\nPort: " + getPort() + "\nUsername: " + getUser() + "\nPassword: " + getPassword() + "\nPath: "
260             + path;
261     }
262 }