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 *
035 */
036public abstract class ScmUrlUtils {
037    private static final String ILLEGAL_SCM_URL =
038            "The scm url must be on the form 'scm:<scm provider><delimiter><provider specific part>' "
039                    + "where <delimiter> can be either ':' or '|'.";
040
041    /**
042     * Get the delimiter used in the scm url.
043     *
044     * @param scmUrl A valid scm url to parse
045     * @return The delimiter used in the scm url
046     */
047    public static String getDelimiter(String scmUrl) {
048        scmUrl = scmUrl.substring(4);
049
050        int index = scmUrl.indexOf('|');
051
052        if (index == -1) {
053            index = scmUrl.indexOf(':');
054
055            if (index == -1) {
056                throw new IllegalArgumentException("The scm url does not contain a valid delimiter.");
057            }
058        }
059
060        return scmUrl.substring(index, index + 1);
061    }
062
063    /**
064     * Get the scm provider from the scm url.
065     *
066     * @param scmUrl A valid scm url to parse
067     * @return The scm provider from the scm url
068     */
069    public static String getProvider(String scmUrl) {
070        String delimiter = getDelimiter(scmUrl);
071
072        scmUrl = scmUrl.substring(4);
073
074        int firstDelimiterIndex = scmUrl.indexOf(delimiter);
075
076        return scmUrl.substring(0, firstDelimiterIndex);
077    }
078
079    /**
080     * Get the provider specific part of the scm url.
081     *
082     * @param scmUrl A valid scm url to parse
083     * @return The provider specific part of the scm url
084     */
085    public static String getProviderSpecificPart(String scmUrl) {
086        String delimiter = getDelimiter(scmUrl);
087
088        scmUrl = scmUrl.substring(4);
089
090        int firstDelimiterIndex = scmUrl.indexOf(delimiter);
091
092        return scmUrl.substring(firstDelimiterIndex + 1);
093    }
094
095    /**
096     * Validate that the scm url is in the correct format.
097     * <p>
098     * <strong>Note</strong>: does not validate scm provider specific format.
099     * </p>
100     *
101     * @param scmUrl The scm url to validate
102     * @return <code>true</code> if the scm url is in the correct format,
103     *         otherwise <code>false</code>
104     */
105    public static boolean isValid(String scmUrl) {
106        List<String> messages = validate(scmUrl);
107
108        return messages.isEmpty();
109    }
110
111    /**
112     * Validate that the scm url is in the correct format.
113     * <p>
114     * <strong>Note</strong>: does not validate scm provider specific format.
115     * </p>
116     *
117     * @param scmUrl The scm url to validate
118     * @return A <code>List</code> that contains the errors that occured
119     */
120    public static List<String> validate(String scmUrl) {
121        List<String> messages = new ArrayList<>();
122
123        if (scmUrl == null) {
124            messages.add("The scm url cannot be null.");
125
126            return messages;
127        }
128
129        if (!scmUrl.startsWith("scm:")) {
130            messages.add("The scm url must start with 'scm:'.");
131
132            return messages;
133        }
134
135        if (scmUrl.length() < 6) {
136            messages.add(ILLEGAL_SCM_URL);
137
138            return messages;
139        }
140
141        try {
142            getDelimiter(scmUrl);
143        } catch (IllegalArgumentException e) {
144            messages.add(e.getMessage());
145        }
146
147        return messages;
148    }
149}