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.io.File; 22 23 import org.apache.maven.resolver.internal.ant.AntRepoSys; 24 import org.apache.tools.ant.Project; 25 import org.apache.tools.ant.Task; 26 import org.apache.tools.ant.types.DataType; 27 import org.apache.tools.ant.types.Reference; 28 29 /** 30 * Represents a custom local Maven repository location in an Ant build script. 31 * <p> 32 * This Ant {@code DataType} allows you to override the default local repository 33 * (typically {@code ~/.m2/repository}) by specifying a custom directory to be used 34 * for dependency resolution, artifact installation, or deployment. 35 * </p> 36 * 37 * <p> 38 * The local repository directory is specified using the {@code dir} attribute. 39 * This can be declared inline or via a shared reference using {@code refid}. 40 * </p> 41 * 42 * <h2>Usage Example:</h2> 43 * <pre>{@code 44 * <localRepository id="custom.repo" dir="target/local-repo"/> 45 * 46 * <resolve> 47 * <localRepo refid="custom.repo"/> 48 * ... 49 * </resolve> 50 * }</pre> 51 * 52 * <h2>Attributes:</h2> 53 * <ul> 54 * <li><strong>dir</strong> — the directory to use as the local repository (required unless using {@code refid})</li> 55 * </ul> 56 * 57 * <p> 58 * If this type is declared without a {@link org.apache.tools.ant.Task} context, 59 * it will automatically register itself with the current project via {@link AntRepoSys#setLocalRepository(LocalRepository)}. 60 * </p> 61 * 62 * <h2>Typical Use Cases:</h2> 63 * <ul> 64 * <li>Using an isolated local repository for reproducible builds</li> 65 * <li>Testing against a temporary or project-scoped repository</li> 66 * <li>Ensuring deployment and resolution do not affect the user's global Maven state</li> 67 * </ul> 68 * 69 * @see #setDir(File) 70 * @see #setRefid(org.apache.tools.ant.types.Reference) 71 * @see org.apache.maven.resolver.internal.ant.tasks.Resolve 72 * @see org.apache.maven.resolver.internal.ant.AntRepoSys 73 */ 74 public class LocalRepository extends DataType { 75 76 private final Task task; 77 78 private File dir; 79 80 /** 81 * Constructs a new {@code LocalRepository} without an owning Ant task. 82 * <p> 83 * This constructor is typically used when the local repository is defined inline 84 * in the build script, allowing it to be automatically registered with the project. 85 * </p> 86 */ 87 public LocalRepository() { 88 this(null); 89 } 90 91 /** 92 * Constructs a new {@code LocalRepository} with an owning Ant task. 93 * <p> 94 * This constructor is used when the local repository is defined within a specific 95 * Ant task context, allowing it to be associated with that task. 96 * </p> 97 * 98 * @param task the Ant task that owns this {@code LocalRepository}, or {@code null} if not associated with a task 99 */ 100 public LocalRepository(Task task) { 101 this.task = task; 102 } 103 104 /** 105 * Sets the Ant project context for this {@code LocalRepository}. 106 * <p> 107 * In addition to the standard behavior of associating this data type with the Ant project, 108 * this method also automatically registers this {@code LocalRepository} with the global 109 * {@link org.apache.maven.resolver.internal.ant.AntRepoSys} instance for the project, 110 * <strong>but only if no owning {@link org.apache.tools.ant.Task} was provided</strong>. 111 * </p> 112 * 113 * <p> 114 * This automatic registration allows this local repository to become the default 115 * used for resolution and deployment tasks within the current build context. 116 * </p> 117 * 118 * @param project the Ant project to associate with this data type 119 * 120 * @see org.apache.maven.resolver.internal.ant.AntRepoSys#setLocalRepository(LocalRepository) 121 * @see #LocalRepository(org.apache.tools.ant.Task) 122 */ 123 @Override 124 public void setProject(Project project) { 125 super.setProject(project); 126 127 if (task == null) { 128 AntRepoSys.getInstance(project).setLocalRepository(this); 129 } 130 } 131 132 /** 133 * Resolves this object if defined as a reference and verifies that it is a 134 * {@code LocalRepository} instance. 135 * 136 * @return the referenced {@code LocalRepository} instance 137 * @throws org.apache.tools.ant.BuildException if the reference is invalid 138 * 139 * @see #setRefid(org.apache.tools.ant.types.Reference) 140 * @see #isReference() 141 */ 142 protected LocalRepository getRef() { 143 return getCheckedRef(LocalRepository.class); 144 } 145 146 /** 147 * Sets a reference to another {@code <localRepository>} definition. 148 * <p> 149 * This allows the current {@code LocalRepository} to act as an alias 150 * for another local repository definition declared elsewhere in the build script. 151 * When a reference is set, all other attributes (such as {@code dir}) must remain unset. 152 * </p> 153 * 154 * <p> 155 * Attempting to set this reference after the {@code dir} attribute has already been specified 156 * will result in an error. 157 * </p> 158 * 159 * @param ref the reference to another {@code LocalRepository} 160 * 161 * @throws org.apache.tools.ant.BuildException if {@code dir} is already set 162 * 163 * @see #getRef() 164 * @see #setDir(File) 165 */ 166 @Override 167 public void setRefid(Reference ref) { 168 if (dir != null) { 169 throw tooManyAttributes(); 170 } 171 super.setRefid(ref); 172 } 173 174 /** 175 * Returns the directory to be used as the local Maven repository. 176 * <p> 177 * If this {@code LocalRepository} is defined as a reference (via {@code refid}), 178 * the method delegates to the referenced instance. 179 * </p> 180 * 181 * @return the local repository directory, or {@code null} if not set 182 * 183 * @see #setDir(File) 184 * @see #setRefid(org.apache.tools.ant.types.Reference) 185 */ 186 public File getDir() { 187 if (isReference()) { 188 return getRef().getDir(); 189 } 190 return dir; 191 } 192 193 /** 194 * Sets the directory to be used as the local Maven repository. 195 * <p> 196 * This directory will be used in place of the default {@code ~/.m2/repository} 197 * for tasks such as dependency resolution, artifact installation, and deployment. 198 * </p> 199 * 200 * <p> 201 * This method may not be used if this object is defined as a reference (i.e., {@code refid} is set). 202 * If the attributes are already configured, an exception will be thrown. 203 * </p> 204 * 205 * @param dir the directory to use as the local repository 206 * 207 * @throws org.apache.tools.ant.BuildException if this instance is a reference or attributes are not allowed 208 * 209 * @see #getDir() 210 * @see #setRefid(org.apache.tools.ant.types.Reference) 211 */ 212 public void setDir(File dir) { 213 checkAttributesAllowed(); 214 this.dir = dir; 215 } 216 }