/* * 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 { 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 exclusions = new ArrayList(); public List inclusions = new ArrayList(); public Date lastPull; public Date nextPull; private Map results = new ConcurrentHashMap(); /** * 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 getStatusList() { List list = new ArrayList(); for (Map.Entry 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 { 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); } } }