1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.resolver.internal.ant.types;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.tools.ant.Task;
25 import org.apache.tools.ant.types.DataType;
26 import org.apache.tools.ant.types.Reference;
27
28 /**
29 * Represents a collection of remote repositories used for dependency resolution or artifact deployment.
30 * <p>
31 * This container allows combining multiple {@link RemoteRepository} and nested {@code <remoterepositories>} elements
32 * into a single referenceable unit. It supports recursive composition and reference resolution through {@code refid}.
33 * </p>
34 *
35 * <p>
36 * This type can be used in Ant build scripts to define reusable sets of repositories.
37 * </p>
38 *
39 * @see RemoteRepository
40 * @see RemoteRepositoryContainer
41 * @see #addRemoterepo(RemoteRepository)
42 * @see #addRemoterepos(RemoteRepositories)
43 */
44 public class RemoteRepositories extends DataType implements RemoteRepositoryContainer {
45
46 private final List<RemoteRepositoryContainer> containers = new ArrayList<>();
47
48 /**
49 * Default constructor for {@code RemoteRepositories} data type.
50 * <p>
51 * Initializes an empty collection of remote repositories.
52 * </p>
53 */
54 public RemoteRepositories() {
55 // Default constructor
56 }
57
58 /**
59 * Resolves this object if defined as a reference and verifies that it is a
60 * {@code RemoteRepositories} instance.
61 *
62 * @return the referenced {@code RemoteRepositories} instance
63 * @throws org.apache.tools.ant.BuildException if the reference is invalid
64 */
65 protected RemoteRepositories getRef() {
66 return getCheckedRef(RemoteRepositories.class);
67 }
68
69 /**
70 * Validates the contained repositories.
71 * <p>
72 * If this object is defined as a reference, validation is delegated to the referenced instance.
73 * Otherwise, each nested {@link RemoteRepositoryContainer} is validated individually.
74 * </p>
75 *
76 * @param task the Ant task requesting validation, used for error reporting
77 */
78 @Override
79 public void validate(Task task) {
80 if (isReference()) {
81 getRef().validate(task);
82 } else {
83 for (RemoteRepositoryContainer container : containers) {
84 container.validate(task);
85 }
86 }
87 }
88
89 /**
90 * Sets a reference to another {@code RemoteRepositories} instance.
91 * <p>
92 * Once a reference is set, this instance must not contain any child elements.
93 * </p>
94 *
95 * @param ref the Ant reference pointing to another {@code RemoteRepositories} object
96 * @throws org.apache.tools.ant.BuildException if this object already contains children
97 */
98 @Override
99 public void setRefid(Reference ref) {
100 if (!containers.isEmpty()) {
101 throw noChildrenAllowed();
102 }
103 super.setRefid(ref);
104 }
105
106 /**
107 * Allow ant to add a single remote repository to the list of containers.
108 *
109 * @param repository the {@link RemoteRepository} to add
110 * @throws org.apache.tools.ant.BuildException if this object is defined as a reference
111 */
112 public void addRemoterepo(RemoteRepository repository) {
113 checkChildrenAllowed();
114 containers.add(repository);
115 }
116
117 /**
118 * Allow Ant to add another {@code RemoteRepositories} instance to this container.
119 * <p>
120 * This allows composition of multiple repository lists.
121 * </p>
122 *
123 * @param repositories the {@code RemoteRepositories} to add
124 * @throws org.apache.tools.ant.BuildException if this object is defined as a reference
125 * @throws org.apache.tools.ant.BuildException if the specified object is the same as this instance (circular reference)
126 */
127 public void addRemoterepos(RemoteRepositories repositories) {
128 checkChildrenAllowed();
129 if (repositories == this) {
130 throw circularReference();
131 }
132 containers.add(repositories);
133 }
134
135 /**
136 * Returns a flattened list of all {@link RemoteRepository} instances contained in this object.
137 * <p>
138 * If this is a reference, the call is delegated to the referenced object.
139 * </p>
140 *
141 * @return the list of remote repositories
142 */
143 @Override
144 public List<RemoteRepository> getRepositories() {
145 if (isReference()) {
146 return getRef().getRepositories();
147 }
148 List<RemoteRepository> repos = new ArrayList<>();
149 for (RemoteRepositoryContainer container : containers) {
150 repos.addAll(container.getRepositories());
151 }
152 return repos;
153 }
154 }