View Javadoc
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   * A container for one or more {@link Artifact} elements in an Ant build script.
30   * <p>
31   * This Ant {@link org.apache.tools.ant.types.DataType} is used to group multiple artifacts,
32   * allowing them to be referenced collectively by tasks such as
33   * {@link org.apache.maven.resolver.internal.ant.tasks.Install Install} or
34   * {@link org.apache.maven.resolver.internal.ant.tasks.Deploy Deploy}.
35   * </p>
36   *
37   * <h2>Usage Example:</h2>
38   * <pre>{@code
39   * <repo:artifacts id="deployment.artifacts">
40   *   <repo:artifact file="target/my-lib.jar" type="jar" groupId="com.example" artifactId="my-lib" version="1.0.0"/>
41   *   <repo:artifact file="target/my-lib.pom" type="pom" groupId="com.example" artifactId="my-lib" version="1.0.0"/>
42   * </repo:artifacts>
43   *
44   * <repo:deploy artifactsRef="deployment.artifacts"/>
45   * }</pre>
46   *
47   * <h2>Attributes:</h2>
48   * <ul>
49   *   <li><strong>id</strong> — Optional reference ID to reuse the container via {@code artifactsRef}.</li>
50   * </ul>
51   *
52   * <h2>Nested Elements:</h2>
53   * <ul>
54   *   <li>{@code <artifact>} — A single Maven artifact definition.</li>
55   *   <li>{@code <artifacts>} — Another nested {@code Artifacts} element, allowing composition.</li>
56   * </ul>
57   *
58   * <p>This class also supports Ant references via {@code refid}, and prevents combining that
59   * with nested artifact declarations.</p>
60   *
61   * @see Artifact
62   * @see ArtifactContainer
63   * @see org.apache.maven.resolver.internal.ant.tasks.Install
64   * @see org.apache.maven.resolver.internal.ant.tasks.Deploy
65   */
66  public class Artifacts extends DataType implements ArtifactContainer {
67  
68      private final List<ArtifactContainer> containers = new ArrayList<>();
69  
70      /**
71       * Default constructor for the {@code Artifacts} data type.
72       */
73      public Artifacts() {
74          // Default constructor
75      }
76  
77      /**
78       * Resolves this object if defined as a reference and verifies that it is a
79       * {@code Artifacts} instance.
80       *
81       * @return the referenced {@code Artifacts} instance
82       * @throws org.apache.tools.ant.BuildException if the reference is invalid
83       */
84      protected Artifacts getRef() {
85          return getCheckedRef(Artifacts.class);
86      }
87  
88      /**
89       * Validates the nested artifact containers.
90       * If this is a reference, delegates to the referenced object.
91       *
92       * @param task the Ant task using this data type
93       * @throws org.apache.tools.ant.BuildException if validation fails
94       */
95      @Override
96      public void validate(Task task) {
97          if (isReference()) {
98              getRef().validate(task);
99          } else {
100             for (ArtifactContainer container : containers) {
101                 container.validate(task);
102             }
103         }
104     }
105 
106     /**
107      * Sets a reference to another {@code Artifacts} instance.
108      *
109      * @param ref the Ant reference
110      * @throws org.apache.tools.ant.BuildException if nested artifacts are already defined
111      */
112     @Override
113     public void setRefid(Reference ref) {
114         if (!containers.isEmpty()) {
115             throw noChildrenAllowed();
116         }
117         super.setRefid(ref);
118     }
119 
120     /**
121      * Allow Ant to add a single {@link Artifact} element to this container.
122      *
123      * @param artifact the artifact to add
124      */
125     public void addArtifact(Artifact artifact) {
126         checkChildrenAllowed();
127         containers.add(artifact);
128     }
129 
130     /**
131      * Allow Ant to add another {@link Artifacts} container as a nested element.
132      *
133      * @param artifacts the nested container to add
134      * @throws org.apache.tools.ant.BuildException if a circular reference is detected
135      */
136     public void addArtifacts(Artifacts artifacts) {
137         checkChildrenAllowed();
138         if (artifacts == this) {
139             throw circularReference();
140         }
141         containers.add(artifacts);
142     }
143 
144     /**
145      * Collects all {@link Artifact} objects from this container and any nested containers.
146      *
147      * @return a list of all artifacts
148      */
149     @Override
150     public List<Artifact> getArtifacts() {
151         if (isReference()) {
152             return getRef().getArtifacts();
153         }
154         List<Artifact> artifacts = new ArrayList<>();
155         for (ArtifactContainer container : containers) {
156             artifacts.addAll(container.getArtifacts());
157         }
158         return artifacts;
159     }
160 }