James Moger
2011-12-22 e6935876b97a63bae2ec087b4fc390c832aef155
commit | author | age
831469 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://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,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.models;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.Date;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import com.gitblit.Constants.FederationPullStatus;
26 import com.gitblit.utils.StringUtils;
27
28 /**
29  * Represents a federated server registration. Gitblit federation allows one
30  * Gitblit instance to pull the repositories and configuration from another
31  * Gitblit instance. This is a backup operation and can be considered something
32  * like svn-sync.
33  * 
34  */
35 public class FederationModel implements Serializable, Comparable<FederationModel> {
36
37     private static final long serialVersionUID = 1L;
38
39     public String name;
40
41     public String url;
42
43     public String token;
44
45     public String frequency;
46
47     public String folder;
d7fb20 48     
JM 49     public boolean bare;
831469 50
2548a7 51     public boolean mirror;
2c32fd 52
831469 53     public boolean mergeAccounts;
JM 54
55     public boolean sendStatus;
56
57     public boolean notifyOnError;
58
59     public List<String> exclusions = new ArrayList<String>();
60
61     public List<String> inclusions = new ArrayList<String>();
62
63     public Date lastPull;
64
65     public Date nextPull;
66
67     private Map<String, FederationPullStatus> results = new ConcurrentHashMap<String, FederationPullStatus>();
68
69     /**
70      * The constructor for a remote server configuration.
71      * 
72      * @param serverName
73      */
74     public FederationModel(String serverName) {
75         this.name = serverName;
f6740d 76         bare = true;
JM 77         mirror = true;
831469 78         this.lastPull = new Date(0);
JM 79         this.nextPull = new Date(0);
80     }
81
82     public boolean isIncluded(RepositoryModel repository) {
83         // if exclusions has the all wildcard, then check for specific
84         // inclusions
85         if (exclusions.contains("*")) {
86             for (String name : inclusions) {
87                 if (StringUtils.fuzzyMatch(repository.name, name)) {
88                     results.put(repository.name, FederationPullStatus.PENDING);
89                     return true;
90                 }
91             }
92             results.put(repository.name, FederationPullStatus.EXCLUDED);
93             return false;
94         }
95
96         // named exclusions
97         for (String name : exclusions) {
98             if (StringUtils.fuzzyMatch(repository.name, name)) {
99                 results.put(repository.name, FederationPullStatus.EXCLUDED);
100                 return false;
101             }
102         }
103
104         // included by default
105         results.put(repository.name, FederationPullStatus.PENDING);
106         return true;
107     }
108
109     /**
110      * Updates the pull status of a particular repository in this federation
111      * registration.
112      * 
113      * @param repository
114      * @param status
115      */
116     public void updateStatus(RepositoryModel repository, FederationPullStatus status) {
117         if (!results.containsKey(repository)) {
118             results.put(repository.name, FederationPullStatus.PENDING);
119         }
120         if (status != null) {
121             results.put(repository.name, status);
122         }
123     }
124
125     public List<RepositoryStatus> getStatusList() {
126         List<RepositoryStatus> list = new ArrayList<RepositoryStatus>();
127         for (Map.Entry<String, FederationPullStatus> entry : results.entrySet()) {
128             list.add(new RepositoryStatus(entry.getKey(), entry.getValue()));
129         }
130         return list;
131     }
132
133     /**
134      * Iterates over the current pull results and returns the lowest pull
135      * status.
136      * 
137      * @return the lowest pull status of the registration
138      */
139     public FederationPullStatus getLowestStatus() {
140         if (results.size() == 0) {
141             return FederationPullStatus.PENDING;
142         }
c729c5 143         FederationPullStatus status = FederationPullStatus.MIRRORED;
831469 144         for (FederationPullStatus result : results.values()) {
JM 145             if (result.ordinal() < status.ordinal()) {
146                 status = result;
147             }
148         }
149         return status;
150     }
151
152     /**
153      * Returns true if this registration represents the result data sent by a
154      * pulling Gitblit instance.
155      * 
156      * @return true, if this is result data
157      */
158     public boolean isResultData() {
159         return !url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://");
160     }
161
162     @Override
163     public String toString() {
164         return "Federated " + name + " (" + url + ")";
165     }
166
167     @Override
168     public int compareTo(FederationModel o) {
169         boolean r1 = isResultData();
170         boolean r2 = o.isResultData();
171         if ((r1 && r2) || (!r1 && !r2)) {
172             // sort registrations and results by name
173             return name.compareTo(o.name);
174         }
175         // sort registrations first
176         if (r1) {
177             return 1;
178         }
179         return -1;
180     }
181
182     /**
183      * Class that encapsulates a point-in-time pull result.
184      * 
185      */
186     public static class RepositoryStatus implements Serializable, Comparable<RepositoryStatus> {
187
188         private static final long serialVersionUID = 1L;
189
190         public final String name;
191         public final FederationPullStatus status;
192
193         RepositoryStatus(String name, FederationPullStatus status) {
194             this.name = name;
195             this.status = status;
196         }
197
198         @Override
199         public int compareTo(RepositoryStatus o) {
200             if (status.equals(o.status)) {
94750e 201                 return StringUtils.compareRepositoryNames(name, o.name);
831469 202             }
JM 203             return status.compareTo(o.status);
204         }
205     }
206 }