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.spring;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.util.Arrays;
21  import java.util.List;
22  import java.util.Properties;
23  
24  import org.apache.commons.io.FileUtils;
25  import org.codehaus.plexus.util.StringUtils;
26  import org.kuali.common.util.LocationUtils;
27  import org.kuali.common.util.ProjectUtils;
28  import org.kuali.common.util.Str;
29  import org.kuali.common.util.property.Constants;
30  import org.kuali.common.util.service.ScmService;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  import org.springframework.beans.factory.annotation.Autowired;
34  import org.springframework.context.annotation.Bean;
35  import org.springframework.context.annotation.Configuration;
36  import org.springframework.core.env.Environment;
37  import org.springframework.util.PropertyPlaceholderHelper;
38  
39  @Configuration
40  public class GenerateGAVConfig {
41  
42  	private static final Logger logger = LoggerFactory.getLogger(GenerateGAVConfig.class);
43  
44  	private static final String FS = File.separator;
45  
46  	@Autowired
47  	Environment env;
48  
49  	@Bean
50  	public Object doGAV() {
51  		// Skip everything
52  		boolean skip = SpringUtils.isTrue(env, "project.gav.skip");
53  		// Validate only, don't create the file or commit it
54  		boolean validate = SpringUtils.isTrue(env, "project.gav.validate");
55  		// Create (or update) the file
56  		boolean update = SpringUtils.isTrue(env, "project.gav.update");
57  		// Commit the file to SCM
58  		boolean commit = SpringUtils.isTrue(env, "project.gav.commit");
59  		if (skip) {
60  			logger.info("Skipping GAV check");
61  			return null;
62  		}
63  		String template = ProjectUtils.getJavaSourceFileTemplate();
64  		String filename = getFilename(env);
65  		File outputFile = new File(filename);
66  		String encoding = SpringUtils.getProperty(env, "project.encoding");
67  		Properties p = getPlaceholderProperties(env);
68  		PropertyPlaceholderHelper pph = Constants.DEFAULT_PROPERTY_PLACEHOLDER_HELPER;
69  		String sourceCode = pph.replacePlaceholders(template, p);
70  		boolean existing = LocationUtils.exists(outputFile);
71  		boolean identical = existingIsIdentical(outputFile, sourceCode, encoding);
72  
73  		// Validate everything matches up, but take no further action
74  		if (validate) {
75  			if (identical) {
76  				logger.info("Verified GAV - [{}]", LocationUtils.getCanonicalPath(outputFile));
77  				return null;
78  			} else {
79  				throw new IllegalStateException("GAV information is out of sync [" + LocationUtils.getCanonicalPath(outputFile) + "]");
80  			}
81  		}
82  
83  		// Nothing to update or commit if this is true
84  		if (identical) {
85  			return null;
86  		}
87  
88  		// Create (or update) the .java file
89  		if (update) {
90  			String action = existing ? "Updating" : "Creating";
91  			logger.info("{} [{}]", action, LocationUtils.getCanonicalPath(outputFile));
92  			write(outputFile, sourceCode);
93  		}
94  
95  		// Commit the .java file to SCM
96  		if (commit) {
97  			ScmService service = getScmService(env);
98  			if (!existing) {
99  				service.add(Arrays.asList(outputFile));
100 			}
101 			logger.info("Committing [{}]", LocationUtils.getCanonicalPath(outputFile));
102 			service.commit(Arrays.asList(outputFile), "Automatically generated java source code - Maven GAV");
103 		}
104 		return null;
105 	}
106 
107 	protected ScmService getScmService(Environment env) {
108 		String scmUrl = SpringUtils.getProperty(env, "project.scm.developerConnection");
109 		ScmServiceFactoryBean ssfb = new ScmServiceFactoryBean();
110 		ssfb.setUrl(scmUrl);
111 		try {
112 			return ssfb.getObject();
113 		} catch (Exception e) {
114 			throw new IllegalArgumentException(e);
115 		}
116 	}
117 
118 	protected void write(File file, String content) {
119 		try {
120 			FileUtils.write(file, content);
121 		} catch (IOException e) {
122 			throw new IllegalStateException(e);
123 		}
124 	}
125 
126 	protected boolean isSkip(Environment env) {
127 		return SpringUtils.isTrue(env, "project.gav.skip");
128 	}
129 
130 	protected Properties getPlaceholderProperties(Environment env) {
131 		String classname = getJavaClassName(SpringUtils.getProperty(env, "project.artifactId"));
132 		List<String> keys = Arrays.asList("project.groupId", "project.artifactId", "project.version");
133 		Properties p = new Properties();
134 		for (String key : keys) {
135 			p.setProperty(key, SpringUtils.getProperty(env, key));
136 		}
137 		p.setProperty("project.artifactId.classname", classname);
138 		return p;
139 	}
140 
141 	protected boolean existingIsIdentical(File file, String newContent, String encoding) {
142 		if (!LocationUtils.exists(file)) {
143 			return false;
144 		}
145 		String cpath = LocationUtils.getCanonicalPath(file);
146 		String oldContent = LocationUtils.toString(cpath, encoding);
147 		return StringUtils.equals(newContent, oldContent);
148 	}
149 
150 	protected String getFilename(Environment env) {
151 		String srcDir = SpringUtils.getProperty(env, "project.build.sourceDirectory");
152 		String groupId = SpringUtils.getProperty(env, "project.groupId");
153 		String artifactId = SpringUtils.getProperty(env, "project.artifactId");
154 		String classname = getJavaClassName(artifactId);
155 
156 		StringBuilder sb = new StringBuilder();
157 		sb.append(srcDir);
158 		sb.append(FS);
159 		sb.append(Str.getPath(groupId));
160 		sb.append(FS);
161 		sb.append(classname);
162 		sb.append(".java");
163 		return sb.toString();
164 	}
165 
166 	protected String getJavaClassName(String artifactId) {
167 		String[] tokens = StringUtils.split(artifactId, "-");
168 		StringBuilder sb = new StringBuilder();
169 		for (String token : tokens) {
170 			String capitalized = StringUtils.capitalizeFirstLetter(token);
171 			sb.append(capitalized);
172 		}
173 		sb.append("GAV");
174 		return sb.toString();
175 	}
176 
177 }