001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm.provider;
020
021import java.util.ArrayList;
022import java.util.List;
023
024/**
025 * A utility class that validates and parses scm url:s. The code here is
026 * <strong>not</strong> scm provider specific.
027 * <p>
028 * If you need methods that work for a specific scm provider, please create a
029 * similar class for that provider. E.g. create the class SvnScmUrlUtils if
030 * you need Subversion-specific checking/parsing.
031 * </p>
032 *
033 * @author <a href="mailto:dennisl@apache.org">Dennis Lundberg</a>
034 */
035public abstract class ScmUrlUtils {
036    private static final String ILLEGAL_SCM_URL =
037            "The scm url must be on the form 'scm:<scm provider><delimiter><provider specific part>' "
038                    + "where <delimiter> can be either ':' or '|'.";
039
040    /**
041     * Get the delimiter used in the scm url.
042     *
043     * @param scmUrl a valid scm url to parse
044     * @return the delimiter used in the scm url
045     */
046    public static String getDelimiter(String scmUrl) {
047        scmUrl = scmUrl.substring(4);
048
049        int index = scmUrl.indexOf('|');
050
051        if (index == -1) {
052            index = scmUrl.indexOf(':');
053
054            if (index == -1) {
055                throw new IllegalArgumentException("The scm url does not contain a valid delimiter.");
056            }
057        }
058
059        return scmUrl.substring(index, index + 1);
060    }
061
062    /**
063     * Get the scm provider from the scm url.
064     *
065     * @param scmUrl a valid scm url to parse
066     * @return the scm provider from the scm url
067     */
068    public static String getProvider(String scmUrl) {
069        String delimiter = getDelimiter(scmUrl);
070
071        scmUrl = scmUrl.substring(4);
072
073        int firstDelimiterIndex = scmUrl.indexOf(delimiter);
074
075        return scmUrl.substring(0, firstDelimiterIndex);
076    }
077
078    /**
079     * Get the provider specific part of the scm url.
080     *
081     * @param scmUrl a valid scm url to parse
082     * @return the provider specific part of the scm url
083     */
084    public static String getProviderSpecificPart(String scmUrl) {
085        String delimiter = getDelimiter(scmUrl);
086
087        scmUrl = scmUrl.substring(4);
088
089        int firstDelimiterIndex = scmUrl.indexOf(delimiter);
090
091        return scmUrl.substring(firstDelimiterIndex + 1);
092    }
093
094    /**
095     * Validate that the scm url is in the correct format.
096     * <p>
097     * <strong>Note</strong>: does not validate scm provider specific format.
098     * </p>
099     *
100     * @param scmUrl the scm url to validate
101     * @return <code>true</code> if the scm url is in the correct format,
102     *         otherwise <code>false</code>
103     */
104    public static boolean isValid(String scmUrl) {
105        List<String> messages = validate(scmUrl);
106
107        return messages.isEmpty();
108    }
109
110    /**
111     * Validate that the scm url is in the correct format.
112     * <p>
113     * <strong>Note</strong>: does not validate scm provider specific format.
114     * </p>
115     *
116     * @param scmUrl the scm url to validate
117     * @return a <code>List</code> that contains the errors that occured
118     */
119    public static List<String> validate(String scmUrl) {
120        List<String> messages = new ArrayList<>();
121
122        if (scmUrl == null) {
123            messages.add("The scm url cannot be null.");
124
125            return messages;
126        }
127
128        if (!scmUrl.startsWith("scm:")) {
129            messages.add("The scm url must start with 'scm:'.");
130
131            return messages;
132        }
133
134        if (scmUrl.length() < 6) {
135            messages.add(ILLEGAL_SCM_URL);
136
137            return messages;
138        }
139
140        try {
141            getDelimiter(scmUrl);
142        } catch (IllegalArgumentException e) {
143            messages.add(e.getMessage());
144        }
145
146        return messages;
147    }
148}