001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.project;
017
018import static org.kuali.common.util.base.Precondition.checkNotBlank;
019
020import java.io.File;
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Properties;
024
025import org.kuali.common.util.Assert;
026import org.kuali.common.util.Str;
027import org.kuali.common.util.file.CanonicalFile;
028import org.kuali.common.util.maven.MavenConstants;
029import org.kuali.common.util.project.model.Build;
030import org.kuali.common.util.project.model.ImmutableProject;
031import org.kuali.common.util.project.model.Project;
032import org.kuali.common.util.project.model.ProjectIdentifier;
033import org.kuali.common.util.project.model.ProjectResource;
034import org.springframework.util.ResourceUtils;
035
036public class ProjectUtils {
037
038        private static final String CLASSPATH = ResourceUtils.CLASSPATH_URL_PREFIX;
039
040        /**
041         * Get a <code>Project</code> from a <code>Properties</code>
042         */
043        public static Project getProject(Properties properties) {
044                String groupId = properties.getProperty(MavenConstants.GROUP_ID_KEY);
045                String artifactId = properties.getProperty(MavenConstants.ARTIFACT_ID_KEY);
046                String version = properties.getProperty(MavenConstants.VERSION_KEY);
047                return new ImmutableProject(groupId, artifactId, version, properties);
048        }
049
050        /**
051         * Convert a project id into a <code>ProjectIdentifier's</code>
052         * 
053         * Example project id:
054         * 
055         * <pre>
056         *   org.kuali.common:kuali-util
057         * </pre>
058         */
059        public static ProjectIdentifier getIdentifier(String projectId) {
060
061                // Project id can't be blank
062                Assert.noBlanks("projectId is blank", projectId);
063
064                // Split up the id
065                String[] tokens = Str.split(projectId, ":", true);
066
067                // Must always have exactly 2 tokens
068                Assert.isTrue(tokens.length == 2, "tokens.length != 2");
069
070                // 1st token is groupId, 2nd token is artifactId
071                String groupId = tokens[0];
072                String artifactId = tokens[1];
073
074                // Create a project identifier from the strings
075                return new ProjectIdentifier(groupId, artifactId);
076        }
077
078        /**
079         * Convert a list of project ids into a list of <code>ProjectIdentifier's</code>
080         * 
081         * Example project id:
082         * 
083         * <pre>
084         *   org.kuali.common:kuali-util
085         * </pre>
086         */
087        public static List<ProjectIdentifier> getIdentifiers(List<String> projectIds) {
088                List<ProjectIdentifier> list = new ArrayList<ProjectIdentifier>();
089                for (String projectId : projectIds) {
090                        ProjectIdentifier element = getIdentifier(projectId);
091                        list.add(element);
092                }
093                return list;
094        }
095
096        /**
097         * Get a build object with local file system directories filled in.
098         * 
099         * The typical directory structure looks like this:
100         * 
101         * <pre>
102         *  kuali-util/
103         *  kuali-util/target
104         *  kuali-util/target/classes
105         * </pre>
106         */
107        public static Build getBuild(Project project) {
108                File projectDir = getBasedir(project);
109                String encoding = getEncoding(project);
110                File buildDir = getBuildDirectory(project);
111                File outputDir = getBuildOutputDirectory(project);
112                File sourceDirectory = new CanonicalFile(project.getProperties().getProperty(MavenConstants.SOURCE_DIRECTORY_KEY));
113                File testOutputDir = new CanonicalFile(project.getProperties().getProperty(MavenConstants.TEST_OUTPUT_DIRECTORY_KEY));
114                File testSourceDir = new CanonicalFile(project.getProperties().getProperty(MavenConstants.TEST_SOURCE_DIRECTORY_KEY));
115                File scriptSourceDirectory = new CanonicalFile(project.getProperties().getProperty(MavenConstants.SCRIPT_SOURCE_DIRECTORY_KEY));
116                return new Build(project, encoding, projectDir, buildDir, outputDir, sourceDirectory, scriptSourceDirectory, testOutputDir, testSourceDir);
117        }
118
119        /**
120         * Convenience method for extracting the value of the property <code>project.build.directory</code>
121         */
122        public static File getBuildDirectory(Project project) {
123                return new CanonicalFile(project.getProperties().getProperty(MavenConstants.BUILD_DIRECTORY_KEY));
124        }
125
126        /**
127         * Convenience method for extracting the value of the property <code>project.basedir</code>
128         */
129        public static File getBasedir(Project project) {
130                return new CanonicalFile(project.getProperties().getProperty(MavenConstants.BASEDIR_KEY));
131        }
132
133        /**
134         * Convenience method for extracting the value of the property <code>project.build.outputDirectory</code>
135         */
136        public static File getBuildOutputDirectory(Project project) {
137                return new CanonicalFile(project.getProperties().getProperty(MavenConstants.BUILD_OUTPUT_DIRECTORY_KEY));
138        }
139
140        /**
141         * Convenience method for extracting the value of the property <code>project.encoding</code>
142         */
143        public static String getEncoding(Project project) {
144                Assert.noNulls(project);
145                return project.getProperties().getProperty(MavenConstants.ENCODING_KEY);
146        }
147
148        /**
149         * Return a resource directory relative to <code>directory</code>
150         * 
151         * <pre>
152         *   /tmp/x/y/z + org.kuali.common:kuali-util  ->  /tmp/x/y/z/org/kuali/common/kuali-util
153         * </pre>
154         */
155        public static File getResourceDirectory(File directory, String groupId, String artifactId) {
156                String path = getResourcePath(groupId, artifactId);
157                return new File(directory, path);
158        }
159
160        /**
161         * Return a resource friendly prefix.
162         * 
163         * <pre>
164         *   org.kuali.common:kuali-util  ->  org/kuali/common/kuali-util
165         * </pre>
166         */
167        public static String getResourcePath(String groupId, String artifactId) {
168                checkNotBlank(groupId, "groupId");
169                checkNotBlank(artifactId, "artifactId");
170                return Str.getPath(groupId) + "/" + artifactId;
171        }
172
173        /**
174         * Return a resource friendly prefix.
175         * 
176         * <pre>
177         *   org.kuali.common:kuali-util  ->  org/kuali/common/kuali-util
178         * </pre>
179         */
180        public static String getResourcePath(ProjectIdentifier pid) {
181                return getResourcePath(pid.getGroupId(), pid.getArtifactId());
182        }
183
184        /**
185         * Use <code>getClasspathPrefix()</code> instead. (lowercase "p" in the word classpath)
186         * 
187         * @deprecated
188         */
189        @Deprecated
190        public static String getClassPathPrefix(String groupId, String artifactId) {
191                return getClasspathPrefix(groupId, artifactId);
192        }
193
194        /**
195         * Return a classpath prefix.
196         * 
197         * <pre>
198         *   org.kuali.common:kuali-util  ->  classpath:org/kuali/common/kuali-util
199         * </pre>
200         */
201        public static String getClasspathPrefix(String groupId, String artifactId) {
202                return CLASSPATH + getResourcePath(groupId, artifactId);
203        }
204
205        /**
206         * Return a classpath prefix.
207         * 
208         * <pre>
209         *   org.kuali.common:kuali-util  ->  classpath:org/kuali/common/kuali-util
210         * </pre>
211         */
212        public static String getClasspathPrefix(ProjectIdentifier project) {
213                return getClasspathPrefix(project.getGroupId(), project.getArtifactId());
214        }
215
216        /**
217         * Return a classpath prefix.
218         * 
219         * <pre>
220         *   org.kuali.common  ->  classpath:org/kuali/common
221         * </pre>
222         */
223        public static String getClasspathPrefix(String groupId) {
224                return CLASSPATH + Str.getPath(groupId);
225        }
226
227        /**
228         * Return a classpath prefix.
229         * 
230         * <pre>
231         *   org.kuali.common:kuali-util:metainf  ->  classpath:org/kuali/common/kuali-util/metainf
232         * </pre>
233         * 
234         * @deprecated
235         */
236        @Deprecated
237        public static String getClasspathPrefix(org.kuali.common.util.project.model.FeatureIdentifier feature) {
238                return getClasspathPrefix(feature.getProject()) + "/" + feature.getFeatureId();
239        }
240
241        /**
242         * <pre>
243         *   classpath:org/kuali/common/kuali-util/myfile.txt
244         * </pre>
245         */
246        public static String getClasspathResource(ProjectIdentifier project, String filename) {
247                return getClasspathPrefix(project.getGroupId(), project.getArtifactId()) + "/" + filename;
248        }
249
250        /**
251         * <pre>
252         *   [prefix]org/kuali/common/kuali-util/[path]
253         * </pre>
254         */
255        public static String getPath(ProjectResource resource) {
256                StringBuilder sb = new StringBuilder();
257                sb.append(resource.getPrefix());
258                ProjectIdentifier project = resource.getProject();
259                sb.append(Str.getPath(project.getGroupId()));
260                sb.append("/");
261                sb.append(project.getArtifactId());
262                sb.append("/");
263                sb.append(resource.getPath());
264                return sb.toString();
265        }
266
267}