001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.util.ArrayList; 007import java.util.Collections; 008import java.util.List; 009import java.util.Stack; 010import java.util.stream.Collectors; 011 012/** 013 * This is an exception that is thrown if the user attempts to upload a list of relations with a cyclic dependency in them 014 * @since 12673 (moved from {@code action.upload} package) 015 */ 016public class CyclicUploadDependencyException extends Exception { 017 private final List<Relation> cycle; 018 019 /** 020 * Creates a new {@link CyclicUploadDependencyException} 021 * @param cycle The cycle that was found 022 */ 023 public CyclicUploadDependencyException(Stack<Relation> cycle) { 024 this.cycle = new ArrayList<>(cycle); 025 } 026 027 protected String formatRelation(Relation r) { 028 StringBuilder sb = new StringBuilder(); 029 if (r.getName() != null) { 030 sb.append('\'').append(r.getName()).append('\''); 031 } else if (!r.isNew()) { 032 sb.append(r.getId()); 033 } else { 034 sb.append("relation@").append(r.hashCode()); 035 } 036 return sb.toString(); 037 } 038 039 @Override 040 public String getMessage() { 041 return cycle.stream().map(this::formatRelation) 042 .collect(Collectors.joining(",", tr("Cyclic dependency between relations:") + '[', "]")); 043 } 044 045 /** 046 * Gets the cycle 047 * @return The cycle that was detected 048 */ 049 public List<Relation> getCyclicUploadDependency() { 050 return Collections.unmodifiableList(cycle); 051 } 052}