1   /*
2    * Copyright 2017 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  
17  package com.linecorp.centraldogma.server.internal.thrift;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.concurrent.CompletableFuture;
22  import java.util.function.Function;
23  import java.util.stream.Collectors;
24  
25  import javax.annotation.Nullable;
26  
27  import com.linecorp.armeria.common.util.Exceptions;
28  import com.linecorp.centraldogma.common.ChangeConflictException;
29  import com.linecorp.centraldogma.common.EntryNotFoundException;
30  import com.linecorp.centraldogma.common.InvalidPushException;
31  import com.linecorp.centraldogma.common.ProjectExistsException;
32  import com.linecorp.centraldogma.common.ProjectNotFoundException;
33  import com.linecorp.centraldogma.common.QueryExecutionException;
34  import com.linecorp.centraldogma.common.RedundantChangeException;
35  import com.linecorp.centraldogma.common.RepositoryExistsException;
36  import com.linecorp.centraldogma.common.RepositoryNotFoundException;
37  import com.linecorp.centraldogma.common.RevisionNotFoundException;
38  import com.linecorp.centraldogma.common.ShuttingDownException;
39  import com.linecorp.centraldogma.internal.thrift.Author;
40  import com.linecorp.centraldogma.internal.thrift.AuthorConverter;
41  import com.linecorp.centraldogma.internal.thrift.CentralDogmaException;
42  import com.linecorp.centraldogma.internal.thrift.Change;
43  import com.linecorp.centraldogma.internal.thrift.ChangeConverter;
44  import com.linecorp.centraldogma.internal.thrift.ChangeType;
45  import com.linecorp.centraldogma.internal.thrift.Commit;
46  import com.linecorp.centraldogma.internal.thrift.CommitConverter;
47  import com.linecorp.centraldogma.internal.thrift.Entry;
48  import com.linecorp.centraldogma.internal.thrift.EntryConverter;
49  import com.linecorp.centraldogma.internal.thrift.EntryType;
50  import com.linecorp.centraldogma.internal.thrift.ErrorCode;
51  import com.linecorp.centraldogma.internal.thrift.Markup;
52  import com.linecorp.centraldogma.internal.thrift.MarkupConverter;
53  import com.linecorp.centraldogma.internal.thrift.MergeQuery;
54  import com.linecorp.centraldogma.internal.thrift.MergeQueryConverter;
55  import com.linecorp.centraldogma.internal.thrift.Project;
56  import com.linecorp.centraldogma.internal.thrift.Query;
57  import com.linecorp.centraldogma.internal.thrift.QueryConverter;
58  import com.linecorp.centraldogma.internal.thrift.Repository;
59  import com.linecorp.centraldogma.internal.thrift.Revision;
60  import com.linecorp.centraldogma.internal.thrift.RevisionConverter;
61  
62  final class Converter {
63  
64      @Nullable
65      static <T, U> List<T> convert(@Nullable Collection<U> list, Function<U, T> mapper) {
66          if (list == null) {
67              return null;
68          }
69          return list.stream().map(mapper).collect(Collectors.toList());
70      }
71  
72      ////////////////
73  
74      ////// Revision
75      static Revision convert(com.linecorp.centraldogma.common.Revision rev) {
76          return RevisionConverter.TO_DATA.convert(rev);
77      }
78  
79      static com.linecorp.centraldogma.common.Revision convert(Revision rev) {
80          return RevisionConverter.TO_MODEL.convert(rev);
81      }
82      ////////////////
83  
84      ////// Author
85      static Author convert(com.linecorp.centraldogma.common.Author author) {
86          return AuthorConverter.TO_DATA.convert(author);
87      }
88  
89      static com.linecorp.centraldogma.common.Author convert(Author author) {
90          return AuthorConverter.TO_MODEL.convert(author);
91      }
92      ////////////////
93  
94      ////// Change
95      static com.linecorp.centraldogma.common.Change<?> convert(Change c) {
96          return ChangeConverter.TO_MODEL.convert(c);
97      }
98  
99      static Change convert(com.linecorp.centraldogma.common.Change<?> c) {
100         return ChangeConverter.TO_DATA.convert(c);
101     }
102     ////////////////
103 
104     ////// Query
105     @SuppressWarnings("unchecked")
106     static <T> com.linecorp.centraldogma.common.Query<T> convert(Query query) {
107         return (com.linecorp.centraldogma.common.Query<T>) QueryConverter.TO_MODEL.convert(query);
108     }
109 
110     static Query convert(com.linecorp.centraldogma.common.Query<?> query) {
111         return QueryConverter.TO_DATA.convert(query);
112     }
113 
114     ////////////////
115 
116     ////// Markup
117     static Markup convert(com.linecorp.centraldogma.common.Markup markup) {
118         return MarkupConverter.TO_DATA.convert(markup);
119     }
120 
121     static com.linecorp.centraldogma.common.Markup convert(Markup markup) {
122         return MarkupConverter.TO_MODEL.convert(markup);
123     }
124     ////////////////
125 
126     ////// EntryType
127     static EntryType convert(com.linecorp.centraldogma.common.EntryType type) {
128         return EntryConverter.convertEntryType(type);
129     }
130     ////////////////
131 
132     ////// MergeQuery
133     static MergeQuery convert(com.linecorp.centraldogma.common.MergeQuery<?> mergeQuery) {
134         return MergeQueryConverter.TO_DATA.convert(mergeQuery);
135     }
136 
137     @SuppressWarnings("unchecked")
138     static <T> com.linecorp.centraldogma.common.MergeQuery<T> convert(MergeQuery mergeQuery) {
139         return (com.linecorp.centraldogma.common.MergeQuery<T>)
140                 MergeQueryConverter.TO_MODEL.convert(mergeQuery);
141     }
142     ////////////////
143 
144     ////// ChangeType
145     @Nullable
146     static ChangeType convert(@Nullable com.linecorp.centraldogma.common.ChangeType type) {
147         if (type == null) {
148             return null;
149         }
150 
151         return ChangeType.valueOf(type.name());
152     }
153     ////////////////
154 
155     static Entry convert(com.linecorp.centraldogma.common.Entry<?> entry) {
156         return EntryConverter.convert(entry);
157     }
158 
159     // The parameter 'project' is not used at the moment, but will be used once schema and plugin support lands.
160     static Project convert(
161             String name, com.linecorp.centraldogma.server.storage.project.Project project) {
162         return new Project(name);
163     }
164 
165     static CompletableFuture<Repository> convert(
166             String name, com.linecorp.centraldogma.server.storage.repository.Repository repo) {
167 
168         return repo.history(
169                 com.linecorp.centraldogma.common.Revision.HEAD,
170                 com.linecorp.centraldogma.common.Revision.HEAD,
171                 com.linecorp.centraldogma.server.storage.repository.Repository.ALL_PATH, 1).thenApply(
172                         history -> new Repository(name).setHead(convert(history.get(0))));
173     }
174 
175     static Commit convert(com.linecorp.centraldogma.common.Commit commit) {
176         return CommitConverter.TO_DATA.convert(commit);
177     }
178 
179     static com.linecorp.centraldogma.common.Commit convert(Commit commit) {
180         return CommitConverter.TO_MODEL.convert(commit);
181     }
182 
183     ////// CentralDogmaException
184     static CentralDogmaException convert(Throwable t) {
185         t = Exceptions.peel(t);
186 
187         if (t instanceof CentralDogmaException) {
188             return (CentralDogmaException) t;
189         }
190 
191         ErrorCode code = ErrorCode.INTERNAL_SERVER_ERROR;
192         if (t instanceof IllegalArgumentException || t instanceof InvalidPushException) {
193             code = ErrorCode.BAD_REQUEST;
194         } else if (t instanceof EntryNotFoundException) {
195             code = ErrorCode.ENTRY_NOT_FOUND;
196         } else if (t instanceof RevisionNotFoundException) {
197             code = ErrorCode.REVISION_NOT_FOUND;
198         } else if (t instanceof QueryExecutionException) {
199             code = ErrorCode.QUERY_FAILURE;
200         } else if (t instanceof RedundantChangeException) {
201             code = ErrorCode.REDUNDANT_CHANGE;
202         } else if (t instanceof ChangeConflictException) {
203             code = ErrorCode.CHANGE_CONFLICT;
204         } else if (t instanceof ProjectNotFoundException) {
205             code = ErrorCode.PROJECT_NOT_FOUND;
206         } else if (t instanceof ProjectExistsException) {
207             code = ErrorCode.PROJECT_EXISTS;
208         } else if (t instanceof RepositoryNotFoundException) {
209             code = ErrorCode.REPOSITORY_NOT_FOUND;
210         } else if (t instanceof RepositoryExistsException) {
211             code = ErrorCode.REPOSITORY_EXISTS;
212         } else if (t instanceof ShuttingDownException) {
213             code = ErrorCode.SHUTTING_DOWN;
214         }
215 
216         final CentralDogmaException cde = new CentralDogmaException(code);
217         cde.setMessage(t.toString());
218         cde.initCause(t);
219         return cde;
220     }
221 
222     private Converter() {}
223 }