001package org.eclipse.aether.util.artifact; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.File; 023import java.util.Map; 024 025import org.eclipse.aether.artifact.AbstractArtifact; 026import org.eclipse.aether.artifact.Artifact; 027 028/** 029 * An artifact whose identity is derived from another artifact. <em>Note:</em> Instances of this class are immutable and 030 * the exposed mutators return new objects rather than changing the current instance. 031 */ 032public final class SubArtifact 033 extends AbstractArtifact 034{ 035 036 private final Artifact mainArtifact; 037 038 private final String classifier; 039 040 private final String extension; 041 042 private final File file; 043 044 private final Map<String, String> properties; 045 046 /** 047 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk 048 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier 049 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be 050 * used to refer to the GPG signature of an artifact. 051 * 052 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}. 053 * @param classifier The classifier for this artifact, may be {@code null} if none. 054 * @param extension The extension for this artifact, may be {@code null} if none. 055 */ 056 public SubArtifact( Artifact mainArtifact, String classifier, String extension ) 057 { 058 this( mainArtifact, classifier, extension, (File) null ); 059 } 060 061 /** 062 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk 063 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier 064 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be 065 * used to refer to the GPG signature of an artifact. 066 * 067 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}. 068 * @param classifier The classifier for this artifact, may be {@code null} if none. 069 * @param extension The extension for this artifact, may be {@code null} if none. 070 * @param file The file for this artifact, may be {@code null} if unresolved. 071 */ 072 public SubArtifact( Artifact mainArtifact, String classifier, String extension, File file ) 073 { 074 this( mainArtifact, classifier, extension, null, file ); 075 } 076 077 /** 078 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk 079 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier 080 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be 081 * used to refer to the GPG signature of an artifact. 082 * 083 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}. 084 * @param classifier The classifier for this artifact, may be {@code null} if none. 085 * @param extension The extension for this artifact, may be {@code null} if none. 086 * @param properties The properties of the artifact, may be {@code null}. 087 */ 088 public SubArtifact( Artifact mainArtifact, String classifier, String extension, Map<String, String> properties ) 089 { 090 this( mainArtifact, classifier, extension, properties, null ); 091 } 092 093 /** 094 * Creates a new sub artifact. The classifier and extension specified for this artifact may use the asterisk 095 * character "*" to refer to the corresponding property of the main artifact. For instance, the classifier 096 * "*-sources" can be used to refer to the source attachment of an artifact. Likewise, the extension "*.asc" can be 097 * used to refer to the GPG signature of an artifact. 098 * 099 * @param mainArtifact The artifact from which to derive the identity, must not be {@code null}. 100 * @param classifier The classifier for this artifact, may be {@code null} if none. 101 * @param extension The extension for this artifact, may be {@code null} if none. 102 * @param properties The properties of the artifact, may be {@code null}. 103 * @param file The file for this artifact, may be {@code null} if unresolved. 104 */ 105 public SubArtifact( Artifact mainArtifact, String classifier, String extension, Map<String, String> properties, 106 File file ) 107 { 108 if ( mainArtifact == null ) 109 { 110 throw new IllegalArgumentException( "no artifact specified" ); 111 } 112 this.mainArtifact = mainArtifact; 113 this.classifier = classifier; 114 this.extension = extension; 115 this.file = file; 116 this.properties = copyProperties( properties ); 117 } 118 119 private SubArtifact( Artifact mainArtifact, String classifier, String extension, File file, 120 Map<String, String> properties ) 121 { 122 // NOTE: This constructor assumes immutability of the provided properties, for internal use only 123 this.mainArtifact = mainArtifact; 124 this.classifier = classifier; 125 this.extension = extension; 126 this.file = file; 127 this.properties = properties; 128 } 129 130 public String getGroupId() 131 { 132 return mainArtifact.getGroupId(); 133 } 134 135 public String getArtifactId() 136 { 137 return mainArtifact.getArtifactId(); 138 } 139 140 public String getVersion() 141 { 142 return mainArtifact.getVersion(); 143 } 144 145 public String getBaseVersion() 146 { 147 return mainArtifact.getBaseVersion(); 148 } 149 150 public boolean isSnapshot() 151 { 152 return mainArtifact.isSnapshot(); 153 } 154 155 public String getClassifier() 156 { 157 return expand( classifier, mainArtifact.getClassifier() ); 158 } 159 160 public String getExtension() 161 { 162 return expand( extension, mainArtifact.getExtension() ); 163 } 164 165 public File getFile() 166 { 167 return file; 168 } 169 170 public Artifact setFile( File file ) 171 { 172 if ( ( this.file == null ) ? file == null : this.file.equals( file ) ) 173 { 174 return this; 175 } 176 return new SubArtifact( mainArtifact, classifier, extension, file, properties ); 177 } 178 179 public Map<String, String> getProperties() 180 { 181 return properties; 182 } 183 184 public Artifact setProperties( Map<String, String> properties ) 185 { 186 if ( this.properties.equals( properties ) || ( properties == null && this.properties.isEmpty() ) ) 187 { 188 return this; 189 } 190 return new SubArtifact( mainArtifact, classifier, extension, properties, file ); 191 } 192 193 private static String expand( String pattern, String replacement ) 194 { 195 String result = ""; 196 if ( pattern != null ) 197 { 198 result = pattern.replace( "*", replacement ); 199 200 if ( replacement.length() <= 0 ) 201 { 202 if ( pattern.startsWith( "*" ) ) 203 { 204 int i = 0; 205 for ( ; i < result.length(); i++ ) 206 { 207 char c = result.charAt( i ); 208 if ( c != '-' && c != '.' ) 209 { 210 break; 211 } 212 } 213 result = result.substring( i ); 214 } 215 if ( pattern.endsWith( "*" ) ) 216 { 217 int i = result.length() - 1; 218 for ( ; i >= 0; i-- ) 219 { 220 char c = result.charAt( i ); 221 if ( c != '-' && c != '.' ) 222 { 223 break; 224 } 225 } 226 result = result.substring( 0, i + 1 ); 227 } 228 } 229 } 230 return result; 231 } 232 233}