1 /*******************************************************************************
2  * Copyright (c) 2011 LWJGL Project and others
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html, and under the terms of the
7  * BSD license, see http://lwjgl.org/license.php for details.
8  *
9  * Contributors:
10  *    Jens von Pilgrim - initial implementation
11  ******************************************************************************/
12 package org.lwjgl.ant;
13 
14 import java.text.SimpleDateFormat;
15 import java.util.Date;
16 
17 import org.apache.tools.ant.BuildException;
18 import org.apache.tools.ant.Task;
19 
20 /**
21  * Normalizes a version number and stores result in a property. The version
22  * number is normalized as "%n.%n.%n", e.g. "2.6" becomes "2.6.0"
23  *
24  * @author 	Jens von Pilgrim
25  * @since 	Nov 14, 2010
26  * @see http://wiki.eclipse.org/index.php/Version_Numbering
27  */
28 public class NormalizeVersion extends Task {
29 
30 	public final static String SEGMENTS[] = { "major", "minor", "service",
31 			"qualifier" };
32 
33 	public final static String VERSION_QUALIFIER_PATTERN = "yyyyMMdd-HHmm";
34 
35 	/**
36 	* name of the property to set
37 	*/
38 	protected String property;
39 
40 	protected String version;
41 
42 	protected boolean addDateQualifier = false;
43 
44 	/**
45 	 * @return the addQualifier
46 	 */
isAddDateQualifier()47 	public boolean isAddDateQualifier() {
48 		return addDateQualifier;
49 	}
50 
51 	/**
52 	 * @param i_addQualifier the addQualifier to set
53 	 */
setAddDateQualifier(boolean i_addDateQualifier)54 	public void setAddDateQualifier(boolean i_addDateQualifier) {
55 		addDateQualifier = i_addDateQualifier;
56 	}
57 
58 	/**
59 	 * @return the property
60 	 */
getProperty()61 	public String getProperty() {
62 		return property;
63 	}
64 
65 	/**
66 	 * @param i_property the property to set
67 	 */
setProperty(String i_property)68 	public void setProperty(String i_property) {
69 		property = i_property;
70 	}
71 
72 	/**
73 	 * @return the versionNumber
74 	 */
getVersion()75 	public String getVersion() {
76 		return version;
77 	}
78 
79 	/**
80 	 * @param i_versionNumber the versionNumber to set
81 	 */
setVersion(String version)82 	public void setVersion(String version) {
83 		this.version = version;
84 	}
85 
86 	/**
87 	* check for errors
88 	* @throws BuildException if we are not configured right
89 	*/
validate()90 	private void validate() {
91 		//validation
92 		if (property == null) {
93 			throw new BuildException("attribute property missing");
94 		}
95 		if (version == null) {
96 			throw new BuildException("attribute version missing");
97 		}
98 		String s = getVersion().trim();
99 		int sn = 0;
100 		boolean qualifier = false;
101 		for (int i = 0; i < s.length(); i++) {
102 			if (s.charAt(i) == '.') {
103 				sn++;
104 			} else {
105 
106 				qualifier = !Character.isDigit(s.charAt(i));
107 				if (sn < 1 && !Character.isDigit(s.charAt(i))) {
108 
109 					throw new BuildException(
110 							"Wrong version format, must contain only digits in the "
111 									+ SEGMENTS[sn] + " segment, was "
112 									+ s.substring(0, i) + ">>" + s.charAt(i)
113 									+ "<<" + s.substring(i + 1));
114 
115 				}
116 			}
117 		}
118 		if ((sn > 2 || qualifier) && isAddDateQualifier()) {
119 			throw new BuildException(
120 					"Cannot add date qualifier, qualifier already specified");
121 		}
122 	}
123 
124 	/**
125 	 * Sets given property with normalized version number accoring to
126 	 * major.minor.service[.qualifier]
127 	 * {@inheritDoc}
128 	 * @see org.apache.tools.ant.Task#execute()
129 	 */
130 	@Override
execute()131 	public void execute() throws BuildException {
132 		validate();
133 		//now exit here if the property is already set
134 		if (getProject().getProperty(property) != null) {
135 			return;
136 		}
137 
138 		String normalizedVersionNumber = doExecute();
139 
140 		getProject().setNewProperty(property, normalizedVersionNumber);
141 	}
142 
143 	/**
144 	 * @return
145 	 */
doExecute()146 	protected String doExecute() {
147 		String s = getVersion().trim();
148 		StringBuilder n = new StringBuilder();
149 		int snIndex = 0;
150 		boolean qualifier = false;
151 
152 		String digits = "";
153 		for (int i = 0; i < s.length(); i++) {
154 			char c = s.charAt(i);
155 			if (Character.isDigit(c) && !qualifier) {
156 				digits += c;
157 			} else if (c == '.') {
158 				if (qualifier) {
159 					throw new BuildException(
160 							"Wrong format, qualifier must not contain a dot in "
161 									+ s);
162 				}
163 				if (snIndex < 3) {
164 					if (digits.length() > 0) {
165 						if (snIndex > 0)
166 							n.append('.');
167 						n.append(digits);
168 						digits = "";
169 						snIndex++;
170 					}
171 				} else {
172 					throw new BuildException(
173 							"Wrong format, expected digit, was " + c
174 									+ " at pos " + i + " of " + s);
175 				}
176 			} else if (Character.isJavaIdentifierPart(c)) {
177 				if (digits.length() > 0) {
178 					throw new BuildException(
179 							"Wrong format, qualifier must not start with digits in "
180 									+ s);
181 				}
182 				if (!qualifier) {
183 					switch (snIndex) {
184 					case 0: // e.g. "beta"
185 						n.append("0");
186 						break;
187 					case 1: // e.g. "1.beta
188 						n.append(".0");
189 					case 2: // e.g. "1.2.beta
190 						n.append(".0");
191 					}
192 					qualifier = true;
193 					n.append('.');
194 				}
195 				n.append(c);
196 			}
197 
198 		}
199 
200 		if (!qualifier) {
201 			if (digits.length() > 0) {
202 				if (snIndex > 0)
203 					n.append('.');
204 				n.append(digits);
205 				snIndex++;
206 			}
207 			switch (snIndex) {
208 			case 0: // e.g. ""
209 				n.append("0");
210 				break;
211 			case 1: // e.g. "1.beta
212 				n.append(".0");
213 			case 2: // e.g. "1.2.beta
214 				n.append(".0");
215 			}
216 			if (isAddDateQualifier())
217 				n.append(createDateQualifier());
218 		} else {
219 			if (isAddDateQualifier()) {
220 				throw new BuildException(
221 						"Cannot add date qualifier, qualifier already specified");
222 			}
223 		}
224 
225 		return n.toString();
226 	}
227 
228 	/**
229 	 * @return
230 	 */
createDateQualifier()231 	private String createDateQualifier() {
232 		return ".v"
233 				+ new SimpleDateFormat(VERSION_QUALIFIER_PATTERN)
234 						.format(new Date());
235 	}
236 
237 }
238