1   /*
2    * Copyright 2019 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package com.linecorp.centraldogma.server.internal.storage.repository;
17  
18  import static com.linecorp.centraldogma.server.mirror.MirrorUtil.normalizePath;
19  
20  import java.io.UnsupportedEncodingException;
21  import java.net.URI;
22  import java.net.URLDecoder;
23  import java.util.regex.Matcher;
24  import java.util.regex.Pattern;
25  
26  /**
27   * A utility class for creating a mirroring task.
28   */
29  public final class MirrorUtil {
30  
31      /**
32       * Splits the specified 'remoteUri' into:
33       * - the actual remote repository URI
34       * - the path in the remote repository
35       * - the branch name.
36       *
37       * <p>e.g. git+ssh://foo.com/bar.git/some-path#master is split into:
38       * - remoteRepoUri: git+ssh://foo.com/bar.git
39       * - remotePath:    /some-path/
40       * - remoteBranch:  master
41       *
42       * <p>e.g. dogma://foo.com/bar/qux.dogma is split into:
43       * - remoteRepoUri: dogma://foo.com/bar/qux.dogma
44       * - remotePath:    / (default)
45       * - remoteBranch:  {@code defaultBranch}
46       */
47      public static String[] split(URI remoteUri, String suffix) {
48          final String host = remoteUri.getHost();
49          if (host == null && !remoteUri.getScheme().endsWith("+file")) {
50              throw new IllegalArgumentException("no host in remoteUri: " + remoteUri);
51          }
52  
53          final String path = remoteUri.getRawPath();
54          if (path == null) {
55              throw new IllegalArgumentException("no path in remoteUri: " + remoteUri);
56          }
57  
58          final Matcher matcher = Pattern.compile("^(.*?\\." + suffix + ")(?:$|/)").matcher(path);
59          if (!matcher.find()) {
60              throw new IllegalArgumentException("no '." + suffix + "' in remoteUri path: " + remoteUri);
61          }
62  
63          final String newRemoteUri;
64          final int port = remoteUri.getPort();
65          if (host != null) {
66              if (port > 0) {
67                  newRemoteUri = remoteUri.getScheme() + "://" + host + ':' + port +
68                                 matcher.group(1);
69              } else {
70                  newRemoteUri = remoteUri.getScheme() + "://" + host + matcher.group(1);
71              }
72          } else {
73              newRemoteUri = remoteUri.getScheme() + "://" + matcher.group(1);
74          }
75  
76          final String remotePath;
77          try {
78              String decoded = URLDecoder.decode(path.substring(matcher.group(1).length()), "UTF-8");
79              decoded = normalizePath(decoded);
80  
81              remotePath = decoded;
82          } catch (UnsupportedEncodingException e) {
83              throw new Error(e);
84          }
85  
86          final String remoteBranch = remoteUri.getFragment();
87  
88          return new String[] { newRemoteUri, remotePath, remoteBranch };
89      }
90  
91      private MirrorUtil() {}
92  }