/* | |
* Copyright 2011 gitblit.com. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.gitblit.models; | |
import java.io.Serializable; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.concurrent.ConcurrentHashMap; | |
import com.gitblit.Constants.FederationPullStatus; | |
import com.gitblit.utils.StringUtils; | |
/** | |
* Represents a federated server registration. Gitblit federation allows one | |
* Gitblit instance to pull the repositories and configuration from another | |
* Gitblit instance. This is a backup operation and can be considered something | |
* like svn-sync. | |
* | |
*/ | |
public class FederationModel implements Serializable, Comparable<FederationModel> { | |
private static final long serialVersionUID = 1L; | |
public String name; | |
public String url; | |
public String token; | |
public String frequency; | |
public String folder; | |
public boolean bare; | |
public boolean mirror; | |
public boolean mergeAccounts; | |
public boolean sendStatus; | |
public boolean notifyOnError; | |
public List<String> exclusions = new ArrayList<String>(); | |
public List<String> inclusions = new ArrayList<String>(); | |
public Date lastPull; | |
public Date nextPull; | |
private Map<String, FederationPullStatus> results = new ConcurrentHashMap<String, FederationPullStatus>(); | |
/** | |
* The constructor for a remote server configuration. | |
* | |
* @param serverName | |
*/ | |
public FederationModel(String serverName) { | |
this.name = serverName; | |
bare = true; | |
mirror = true; | |
this.lastPull = new Date(0); | |
this.nextPull = new Date(0); | |
} | |
public boolean isIncluded(RepositoryModel repository) { | |
// if exclusions has the all wildcard, then check for specific | |
// inclusions | |
if (exclusions.contains("*")) { | |
for (String name : inclusions) { | |
if (StringUtils.fuzzyMatch(repository.name, name)) { | |
results.put(repository.name, FederationPullStatus.PENDING); | |
return true; | |
} | |
} | |
results.put(repository.name, FederationPullStatus.EXCLUDED); | |
return false; | |
} | |
// named exclusions | |
for (String name : exclusions) { | |
if (StringUtils.fuzzyMatch(repository.name, name)) { | |
results.put(repository.name, FederationPullStatus.EXCLUDED); | |
return false; | |
} | |
} | |
// included by default | |
results.put(repository.name, FederationPullStatus.PENDING); | |
return true; | |
} | |
/** | |
* Updates the pull status of a particular repository in this federation | |
* registration. | |
* | |
* @param repository | |
* @param status | |
*/ | |
public void updateStatus(RepositoryModel repository, FederationPullStatus status) { | |
if (!results.containsKey(repository.name)) { | |
results.put(repository.name, FederationPullStatus.PENDING); | |
} | |
if (status != null) { | |
results.put(repository.name, status); | |
} | |
} | |
public List<RepositoryStatus> getStatusList() { | |
List<RepositoryStatus> list = new ArrayList<RepositoryStatus>(); | |
for (Map.Entry<String, FederationPullStatus> entry : results.entrySet()) { | |
list.add(new RepositoryStatus(entry.getKey(), entry.getValue())); | |
} | |
return list; | |
} | |
/** | |
* Iterates over the current pull results and returns the lowest pull | |
* status. | |
* | |
* @return the lowest pull status of the registration | |
*/ | |
public FederationPullStatus getLowestStatus() { | |
if (results.size() == 0) { | |
return FederationPullStatus.PENDING; | |
} | |
FederationPullStatus status = FederationPullStatus.MIRRORED; | |
for (FederationPullStatus result : results.values()) { | |
if (result.ordinal() < status.ordinal()) { | |
status = result; | |
} | |
} | |
return status; | |
} | |
/** | |
* Returns true if this registration represents the result data sent by a | |
* pulling Gitblit instance. | |
* | |
* @return true, if this is result data | |
*/ | |
public boolean isResultData() { | |
return !url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://"); | |
} | |
@Override | |
public String toString() { | |
return "Federated " + name + " (" + url + ")"; | |
} | |
@Override | |
public int compareTo(FederationModel o) { | |
boolean r1 = isResultData(); | |
boolean r2 = o.isResultData(); | |
if ((r1 && r2) || (!r1 && !r2)) { | |
// sort registrations and results by name | |
return name.compareTo(o.name); | |
} | |
// sort registrations first | |
if (r1) { | |
return 1; | |
} | |
return -1; | |
} | |
/** | |
* Class that encapsulates a point-in-time pull result. | |
* | |
*/ | |
public static class RepositoryStatus implements Serializable, Comparable<RepositoryStatus> { | |
private static final long serialVersionUID = 1L; | |
public final String name; | |
public final FederationPullStatus status; | |
RepositoryStatus(String name, FederationPullStatus status) { | |
this.name = name; | |
this.status = status; | |
} | |
@Override | |
public int compareTo(RepositoryStatus o) { | |
if (status.equals(o.status)) { | |
return StringUtils.compareRepositoryNames(name, o.name); | |
} | |
return status.compareTo(o.status); | |
} | |
} | |
} |