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