001    package org.apache.maven.scm.provider.hg.repository;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
023    import org.codehaus.plexus.util.StringUtils;
024    
025    import java.io.File;
026    
027    /**
028     * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
029     * @version $Id: HgScmProviderRepository.java 1134851 2011-06-12 01:24:05Z godin $
030     */
031    public class HgScmProviderRepository
032        extends ScmProviderRepositoryWithHost
033    {
034        //Known and tested protocols
035        private static final String FILE = "";
036    
037        private static final String SFTP = "sftp://";
038    
039        private static final String FTP = "ftp://";
040    
041        private static final String AFTP = "aftp://";
042    
043        private static final String HTTP = "http://";
044    
045        private static final String HTTPS = "https://";
046    
047        private final String path;
048    
049        private final String protocol;
050    
051        private final String orgUrl;
052    
053        public HgScmProviderRepository( String url )
054        {
055            orgUrl = url;
056            protocol = getProtocol( url );
057            path = parseUrl( url );
058        }
059    
060        public String getURI()
061        {
062            return protocol + addAuthority() + addHost() + addPort() + addPath();
063        }
064    
065        /**
066         * @return A message if the repository as an invalid URI, null if the URI seems fine.
067         */
068        public String validateURI()
069        {
070    
071            String msg = null;
072    
073            if ( needsAuthentication() )
074            {
075                if ( getUser() == null )
076                {
077                    msg = "Username is missing for protocol " + protocol;
078                }
079                else if ( getPassword() == null )
080                {
081                    msg = "Password is missing for protocol " + protocol;
082                }
083                else if ( getHost() == null )
084                {
085                    msg = "Host (eg. www.myhost.com) is missing for protocol " + protocol;
086                }
087            }
088    
089            else if ( getPort() != 0 && getHost() == null )
090            {
091                msg = "Got port information without any host for protocol " + protocol;
092            }
093    
094            if ( msg != null )
095            {
096                msg =
097                    "Something could be wrong about the repository URL: " + orgUrl + "\nReason: " + msg
098                        + "\nCheck http://maven.apache.org/scm for usage and hints.";
099            }
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                }
153    
154                int indexColon = hostPort.indexOf( ':' );
155                if ( indexColon > 0 )
156                {
157                    setHost( hostPort.substring( 0, indexColon ) );
158                    url = StringUtils.replace( url, getHost(), "" );
159                    setPort( Integer.parseInt( hostPort.substring( indexColon + 1 ) ) );
160                    url = StringUtils.replace( url, ":" + getPort(), "" );
161                }
162                else
163                {
164                    setHost( hostPort );
165                    url = StringUtils.replace( url, getHost(), "" );
166                }
167            }
168    
169            return url;
170        }
171    
172        private String parseUsernameAndPassword( String url )
173        {
174            if ( canAuthenticate() )
175            {
176                String[] split = url.split( "@" );
177                if ( split.length == 2 )
178                {
179                    url = split[1]; //Strip away 'username:password@' from url
180                    split = split[0].split( ":" );
181                    if ( split.length == 2 )
182                    { //both username and password
183                        setUser( split[0] );
184                        setPassword( split[1] );
185                    }
186                    else
187                    { //only username
188                        setUser( split[0] );
189                    }
190                }
191            }
192            return url;
193        }
194    
195        private String parsePath( String url )
196        {
197            if ( protocol == FILE )
198            {
199                //Use OS dependent path separator
200                url = StringUtils.replace( url, "/", File.separator );
201    
202                //Test first path separator (*nix systems use them to denote root)
203                File tmpFile = new File( url ); //most likly a *nix system
204                String url2 = url.substring( File.pathSeparator.length() );
205                File tmpFile2 = new File( url2 ); //most likly a windows system
206                if ( !tmpFile.exists() && !tmpFile2.exists() )
207                {
208                    // This is trouble - Trouble is reported in validateURI()
209                }
210    
211                url = tmpFile2.exists() ? url2 : url;
212            }
213    
214            return url;
215        }
216    
217        private String addUser()
218        {
219            return ( getUser() == null ) ? "" : getUser();
220        }
221    
222        private String addPassword()
223        {
224            return ( getPassword() == null ) ? "" : ":" + getPassword();
225        }
226    
227        private String addHost()
228        {
229            return ( getHost() == null ) ? "" : getHost();
230        }
231    
232        private String addPort()
233        {
234            return ( getPort() == 0 ) ? "" : ":" + getPort();
235        }
236    
237        private String addPath()
238        {
239            return path;
240        }
241    
242        private boolean needsAuthentication()
243        {
244            return protocol == SFTP || protocol == FTP || protocol == HTTPS || protocol == AFTP;
245        }
246    
247        private String addAuthority()
248        {
249            return ( (canAuthenticate() && (getUser() != null))
250                    ? addUser() + addPassword() + "@"
251                    : "" );
252        }
253    
254    
255        private boolean canAuthenticate()
256        {
257            return needsAuthentication() || protocol == HTTP;
258        }
259        /** {@inheritDoc} */
260        public String toString()
261        {
262            return "Hg Repository Interpreted from: " + orgUrl + ":\nProtocol: " + protocol + "\nHost: " + getHost()
263                + "\nPort: " + getPort() + "\nUsername: " + getUser() + "\nPassword: " + getPassword() + "\nPath: "
264                + path;
265        }
266    }