View Javadoc

1   /**
2    * Copyright 2010-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.util;
17  
18  import java.io.File;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.io.FileUtils;
23  import org.apache.commons.lang3.StringUtils;
24  import org.kuali.common.util.nullify.NullUtils;
25  
26  public class RepositoryUtils {
27  
28  	private static final String FS = File.separator;
29  	private static final String DEFAULT_MAVEN_REPO_PATH = ".m2" + FS + "repository";
30  	private static final String GAV_DELIMITER = ":";
31  
32  	public static final void copyArtifact(String repository, Artifact artifact) {
33  		File file = getFile(artifact);
34  		copyArtifactToFile(repository, artifact, file);
35  	}
36  
37  	public static final void copyArtifactToDirectory(String repository, Artifact artifact, File directory) {
38  		String filename = getFilename(artifact);
39  		File file = new File(directory, filename);
40  		copyArtifactToFile(repository, artifact, file);
41  	}
42  
43  	public static final void copyArtifactToFile(String repository, Artifact artifact, File file) {
44  		String location = repository + getRepositoryPath(artifact);
45  		LocationUtils.copyLocationToFile(location, file);
46  	}
47  
48  	/**
49  	 * <p>
50  	 * Order is <code>groupId:artifactId:version:classifier:type</code>. The ordering here matches the order Maven uses to create actual files. Which is different from what the
51  	 * toString() method on Maven's Artifact object produces.
52  	 * </p>
53  	 * 
54  	 * <p>
55  	 * Trailing <code>:</code>'s are omitted.
56  	 * </p>
57  	 * 
58  	 * <p>
59  	 * If every field is left blank, <code>::::</code> is returned.
60  	 * </p>
61  	 * 
62  	 * <pre>
63  	 *   org.kuali.common:kuali-jdbc:1.0.0:webapp:jar  - groupId + artifactId + version + classifier + type
64  	 *   org.kuali.common:kuali-jdbc:1.0.0::jar        - no classifier
65  	 *   ::::                                          - Every field is blank
66  	 *   org.kuali.common                              - groupId only
67  	 *   ::::jar                                       - type only
68  	 *   :kuali-jdbc:::jar                             - no groupId, version, classifier, or type 
69  	 *   org.kuali.common:kuali-jdbc                   - groupId + artifactId
70  	 *   org.kuali.common:kuali-jdbc:1.0.0             - groupId + artifactId + version 
71  	 *   org.kuali.common:kuali-jdbc:1.0.0:webapp      - no type
72  	 *   org.kuali.common:kuali-jdbc:1.0.0             - no classifier or type
73  	 *   org.kuali.common:kuali-jdbc::webapp:jar       - no version
74  	 * </pre>
75  	 */
76  	public static final String toString(Artifact artifact) {
77  		List<String> tokens = new ArrayList<String>();
78  		tokens.add(toEmpty(artifact.getGroupId()));
79  		tokens.add(toEmpty(artifact.getArtifactId()));
80  		tokens.add(toEmpty(artifact.getVersion()));
81  		tokens.add(toEmpty(artifact.getClassifier()));
82  		tokens.add(toEmpty(artifact.getType()));
83  		int delimiterCount = getDelimiterCount(tokens);
84  		return getDelimitedString(tokens, delimiterCount, GAV_DELIMITER);
85  	}
86  
87  	/**
88  	 * <p>
89  	 * Order is <code>groupId:artifactId:version:classifier:type:scope</code>. The ordering here matches the order Maven uses to create actual files. As opposed to what the
90  	 * toString() method on Maven's Dependency object produces.
91  	 * </p>
92  	 * 
93  	 * <p>
94  	 * Trailing <code>:</code>'s are omitted.
95  	 * </p>
96  	 * 
97  	 * <p>
98  	 * If every field is left blank, <code>:::::</code> is returned.
99  	 * </p>
100 	 * 
101 	 * <pre>
102 	 *   org.kuali.common:kuali-jdbc:1.0.0:webapp:jar:compile - groupId + artifactId + version + classifier + type + scope
103 	 *   org.kuali.common:kuali-jdbc:1.0.0::jar:compile       - no classifier
104 	 *   org.kuali.common:kuali-jdbc:1.0.0:webapp:jar:        - no scope
105 	 *   :::::                                                - Every field is blank
106 	 *   org.kuali.common                                     - groupId only
107 	 *   :::::compile                                         - scope only
108 	 *   :kuali-jdbc:::jar                                    - artifactId + type 
109 	 *   org.kuali.common:kuali-jdbc                          - groupId + artifactId
110 	 *   org.kuali.common:kuali-jdbc:1.0.0                    - groupId + artifactId + version 
111 	 *   org.kuali.common:kuali-jdbc:1.0.0:webapp             - groupId + artifactId + version + classifier
112 	 *   org.kuali.common:kuali-jdbc:1.0.0:::compile          - no classifier or type
113 	 *   org.kuali.common:kuali-jdbc::webapp:jar:compile      - no version
114 	 * </pre>
115 	 */
116 	public static final String toString(Dependency dependency) {
117 		List<String> tokens = new ArrayList<String>();
118 		tokens.add(toEmpty(dependency.getGroupId()));
119 		tokens.add(toEmpty(dependency.getArtifactId()));
120 		tokens.add(toEmpty(dependency.getVersion()));
121 		tokens.add(toEmpty(dependency.getClassifier()));
122 		tokens.add(toEmpty(dependency.getType()));
123 		tokens.add(toEmpty(dependency.getScope()));
124 		int delimiterCount = getDelimiterCount(tokens);
125 		return getDelimitedString(tokens, delimiterCount, GAV_DELIMITER);
126 	}
127 
128 	/**
129 	 * <p>
130 	 * Order is <code>groupId:artifactId:version:classifier:type:scope</code>.
131 	 * </p>
132 	 */
133 	public static final Artifact parseArtifact(String gav) {
134 		Assert.hasText(gav, "gav has no text");
135 
136 		String[] tokens = StringUtils.splitPreserveAllTokens(gav, GAV_DELIMITER);
137 		int len = tokens.length;
138 		for (int i = 0; i < len; i++) {
139 			tokens[i] = toNull(tokens[i]);
140 		}
141 
142 		Artifact a = new Artifact();
143 		if (len > 0) {
144 			a.setGroupId(tokens[0]);
145 		}
146 		if (len > 1) {
147 			a.setArtifactId(tokens[1]);
148 		}
149 		if (len > 2) {
150 			a.setVersion(tokens[2]);
151 		}
152 		if (len > 3) {
153 			a.setClassifier(tokens[3]);
154 		}
155 		if (len > 4) {
156 			a.setType(tokens[4]);
157 		}
158 		return a;
159 	}
160 
161 	/**
162 	 * <p>
163 	 * Order is <code>groupId:artifactId:version:classifier:type:scope</code>.
164 	 * </p>
165 	 */
166 	public static final Dependency parseDependency(String gav) {
167 		Assert.hasText(gav, "gav has no text");
168 
169 		String[] tokens = StringUtils.splitPreserveAllTokens(gav, GAV_DELIMITER);
170 		int len = tokens.length;
171 		for (int i = 0; i < len; i++) {
172 			tokens[i] = toNull(tokens[i]);
173 		}
174 
175 		Dependency d = new Dependency();
176 		if (len > 0) {
177 			d.setGroupId(tokens[0]);
178 		}
179 		if (len > 1) {
180 			d.setArtifactId(tokens[1]);
181 		}
182 		if (len > 2) {
183 			d.setVersion(tokens[2]);
184 		}
185 		if (len > 3) {
186 			d.setClassifier(tokens[3]);
187 		}
188 		if (len > 4) {
189 			d.setType(tokens[4]);
190 		}
191 		if (len > 5) {
192 			d.setScope(tokens[5]);
193 		}
194 		return d;
195 	}
196 
197 	protected static final String getDelimitedString(List<String> tokens, int delimiterCount, String delimiter) {
198 		StringBuilder sb = new StringBuilder();
199 		for (int i = 0; i < tokens.size(); i++) {
200 			if (i != 0 && i < delimiterCount) {
201 				sb.append(delimiter);
202 			}
203 			sb.append(tokens.get(i));
204 		}
205 		return sb.toString();
206 	}
207 
208 	protected static final int getDelimiterCount(List<String> tokens) {
209 		int count = 0;
210 		for (int i = 0; i < tokens.size(); i++) {
211 			String token = toEmpty(tokens.get(i));
212 			if (!StringUtils.isEmpty(token)) {
213 				count = i + 1;
214 			}
215 		}
216 		return count == 0 ? tokens.size() : count;
217 	}
218 
219 	/**
220 	 * Return null if token is blank, "NULL", or "NONE"
221 	 */
222 	public static String toNull(String token) {
223 		if (StringUtils.isBlank(token)) {
224 			return null;
225 		}
226 		if (NullUtils.isNullOrNone(token)) {
227 			return null;
228 		}
229 		return token;
230 	}
231 
232 	/**
233 	 * Return the empty string if token is blank, "NULL", or "NONE"
234 	 */
235 	public static String toEmpty(String token) {
236 		if (StringUtils.isBlank(token)) {
237 			return "";
238 		}
239 		if (NullUtils.isNullOrNone(token)) {
240 			return "";
241 		}
242 		return token;
243 	}
244 
245 	public static final String getRepositoryPath(Artifact artifact) {
246 		StringBuilder sb = new StringBuilder();
247 		sb.append(Str.getPath(artifact.getGroupId()));
248 		sb.append(FS);
249 		sb.append(artifact.getArtifactId());
250 		sb.append(FS);
251 		sb.append(artifact.getVersion());
252 		return sb.toString();
253 	}
254 
255 	/**
256 	 * Return true if classifier should become part of the filename
257 	 */
258 	protected static boolean addClassifierToFilename(String classifier) {
259 		return !StringUtils.isBlank(classifier) && !NullUtils.isNullOrNone(classifier);
260 	}
261 
262 	public static final String getFilename(Artifact artifact) {
263 		StringBuilder sb = new StringBuilder();
264 		sb.append(artifact.getArtifactId());
265 		sb.append("-");
266 		sb.append(artifact.getVersion());
267 		if (addClassifierToFilename(artifact.getClassifier())) {
268 			sb.append("-");
269 			sb.append(artifact.getClassifier());
270 		}
271 		sb.append(".");
272 		sb.append(artifact.getType());
273 		return sb.toString();
274 	}
275 
276 	public static final File getDefaultLocalRepositoryDir() {
277 		return new File(FileUtils.getUserDirectoryPath() + FS + DEFAULT_MAVEN_REPO_PATH);
278 	}
279 
280 	public static final File getFile(Artifact artifact) {
281 		return getFile(getDefaultLocalRepositoryDir(), artifact);
282 	}
283 
284 	public static final File getFile(File localRepositoryDir, Artifact artifact) {
285 		String path = getRepositoryPath(artifact);
286 		String filename = getFilename(artifact);
287 		return new File(localRepositoryDir.getAbsolutePath() + FS + path, filename);
288 	}
289 
290 }