All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.project.ProjectHierarchyIterator Maven / Gradle / Ivy

The newest version!
// Copyright (C) 2013 The Android Open Source Project
//
// 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.google.gerrit.server.project;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.config.AllProjectsName;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;

/**
 * Iterates from a project up through its parents to All-Projects.
 *
 * 

If a cycle is detected the cycle is broken and All-Projects is visited. */ class ProjectHierarchyIterator implements Iterator { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final ProjectCache cache; private final AllProjectsName allProjectsName; private final Set seen; private ProjectState next; ProjectHierarchyIterator(ProjectCache c, AllProjectsName all, ProjectState firstResult) { cache = c; allProjectsName = all; seen = Sets.newLinkedHashSet(); seen.add(firstResult.getNameKey()); next = firstResult; } @Override public boolean hasNext() { return next != null; } @Override public ProjectState next() { ProjectState n = next; if (n == null) { throw new NoSuchElementException(); } next = computeNext(n); return n; } @Nullable private ProjectState computeNext(ProjectState n) { Project.NameKey parentName = n.getProject().getParent(); if (parentName != null && visit(parentName)) { Optional p = cache.get(parentName); if (p.isPresent()) { return p.get(); } } // Parent does not exist or was already visited. // Fall back to visit All-Projects exactly once. if (seen.add(allProjectsName)) { return cache.getAllProjects(); } return null; } private boolean visit(Project.NameKey parentName) { if (seen.add(parentName)) { return true; } List order = Lists.newArrayListWithCapacity(seen.size() + 1); for (Project.NameKey p : seen) { order.add(p.get()); } int idx = order.lastIndexOf(parentName.get()); order.add(parentName.get()); logger.atWarning().log( "Cycle detected in projects: %s", Joiner.on(" -> ").join(order.subList(idx, order.size()))); return false; } @Override public void remove() { throw new UnsupportedOperationException(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy