1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.util.ArrayList ; 22 import java.util.List ; 23 import java.util.Iterator ; 24 import java.util.Locale ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import java.util.HashSet ; 28 import java.util.HashMap ; 29 import java.util.Hashtable ; 30 import java.util.Enumeration ; 31 32 import org.apache.tools.ant.BuildException; 33 import org.apache.tools.ant.DynamicAttribute; 34 import org.apache.tools.ant.ProjectHelper; 35 import org.apache.tools.ant.RuntimeConfigurable; 36 import org.apache.tools.ant.Target; 37 import org.apache.tools.ant.Task; 38 import org.apache.tools.ant.TaskContainer; 39 import org.apache.tools.ant.UnknownElement; 40 41 48 public class MacroInstance extends Task implements DynamicAttribute, TaskContainer { 49 private MacroDef macroDef; 50 private Map map = new HashMap (); 51 private Map nsElements = null; 52 private Map presentElements; 53 private Hashtable localAttributes; 54 private String text = null; 55 private String implicitTag = null; 56 private List unknownElements = new ArrayList (); 57 58 63 public void setMacroDef(MacroDef macroDef) { 64 this.macroDef = macroDef; 65 } 66 67 70 public MacroDef getMacroDef() { 71 return macroDef; 72 } 73 74 80 public void setDynamicAttribute(String name, String value) { 81 map.put(name, value); 82 } 83 84 91 public Object createDynamicElement(String name) throws BuildException { 92 throw new BuildException("Not implemented any more"); 93 } 94 95 private Map getNsElements() { 96 if (nsElements == null) { 97 nsElements = new HashMap (); 98 for (Iterator i = macroDef.getElements().entrySet().iterator(); 99 i.hasNext();) { 100 Map.Entry entry = (Map.Entry ) i.next(); 101 nsElements.put((String ) entry.getKey(), 102 entry.getValue()); 103 MacroDef.TemplateElement te = (MacroDef.TemplateElement) 104 entry.getValue(); 105 if (te.isImplicit()) { 106 implicitTag = te.getName(); 107 } 108 } 109 } 110 return nsElements; 111 } 112 113 118 public void addTask(Task nestedTask) { 119 unknownElements.add(nestedTask); 120 } 121 122 private void processTasks() { 123 if (implicitTag != null) { 124 return; 125 } 126 for (Iterator i = unknownElements.iterator(); i.hasNext();) { 127 UnknownElement ue = (UnknownElement) i.next(); 128 String name = ProjectHelper.extractNameFromComponentName( 129 ue.getTag()).toLowerCase(Locale.US); 130 if (getNsElements().get(name) == null) { 131 throw new BuildException("unsupported element " + name); 132 } 133 if (presentElements.get(name) != null) { 134 throw new BuildException("Element " + name + " already present"); 135 } 136 presentElements.put(name, ue); 137 } 138 } 139 140 143 public static class Element implements TaskContainer { 144 private List unknownElements = new ArrayList (); 145 146 151 public void addTask(Task nestedTask) { 152 unknownElements.add(nestedTask); 153 } 154 155 158 public List getUnknownElements() { 159 return unknownElements; 160 } 161 } 162 163 private static final int STATE_NORMAL = 0; 164 private static final int STATE_EXPECT_BRACKET = 1; 165 private static final int STATE_EXPECT_NAME = 2; 166 167 private String macroSubs(String s, Map macroMapping) { 168 if (s == null) { 169 return null; 170 } 171 StringBuffer ret = new StringBuffer (); 172 StringBuffer macroName = null; 173 174 int state = STATE_NORMAL; 175 for (int i = 0; i < s.length(); ++i) { 176 char ch = s.charAt(i); 177 switch (state) { 178 case STATE_NORMAL: 179 if (ch == '@') { 180 state = STATE_EXPECT_BRACKET; 181 } else { 182 ret.append(ch); 183 } 184 break; 185 case STATE_EXPECT_BRACKET: 186 if (ch == '{') { 187 state = STATE_EXPECT_NAME; 188 macroName = new StringBuffer (); 189 } else if (ch == '@') { 190 state = STATE_NORMAL; 191 ret.append('@'); 192 } else { 193 state = STATE_NORMAL; 194 ret.append('@'); 195 ret.append(ch); 196 } 197 break; 198 case STATE_EXPECT_NAME: 199 if (ch == '}') { 200 state = STATE_NORMAL; 201 String name = macroName.toString().toLowerCase(Locale.US); 202 String value = (String ) macroMapping.get(name); 203 if (value == null) { 204 ret.append("@{"); 205 ret.append(name); 206 ret.append("}"); 207 } else { 208 ret.append(value); 209 } 210 macroName = null; 211 } else { 212 macroName.append(ch); 213 } 214 break; 215 default: 216 break; 217 } 218 } 219 switch (state) { 220 case STATE_NORMAL: 221 break; 222 case STATE_EXPECT_BRACKET: 223 ret.append('@'); 224 break; 225 case STATE_EXPECT_NAME: 226 ret.append("@{"); 227 ret.append(macroName.toString()); 228 break; 229 default: 230 break; 231 } 232 233 return ret.toString(); 234 } 235 236 240 241 public void addText(String text) { 242 this.text = text; 243 } 244 245 private UnknownElement copy(UnknownElement ue) { 246 UnknownElement ret = new UnknownElement(ue.getTag()); 247 ret.setNamespace(ue.getNamespace()); 248 ret.setProject(getProject()); 249 ret.setQName(ue.getQName()); 250 ret.setTaskType(ue.getTaskType()); 251 ret.setTaskName(ue.getTaskName()); 252 ret.setLocation( 253 macroDef.getBackTrace() ? ue.getLocation() : getLocation()); 254 if (getOwningTarget() == null) { 255 Target t = new Target(); 256 t.setProject(getProject()); 257 ret.setOwningTarget(t); 258 } else { 259 ret.setOwningTarget(getOwningTarget()); 260 } 261 RuntimeConfigurable rc = new RuntimeConfigurable( 262 ret, ue.getTaskName()); 263 rc.setPolyType(ue.getWrapper().getPolyType()); 264 Map m = ue.getWrapper().getAttributeMap(); 265 for (Iterator i = m.entrySet().iterator(); i.hasNext();) { 266 Map.Entry entry = (Map.Entry ) i.next(); 267 rc.setAttribute( 268 (String ) entry.getKey(), 269 macroSubs((String ) entry.getValue(), localAttributes)); 270 } 271 rc.addText(macroSubs(ue.getWrapper().getText().toString(), 272 localAttributes)); 273 274 Enumeration e = ue.getWrapper().getChildren(); 275 while (e.hasMoreElements()) { 276 RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement(); 277 UnknownElement unknownElement = (UnknownElement) r.getProxy(); 278 String tag = unknownElement.getTaskType(); 279 if (tag != null) { 280 tag = tag.toLowerCase(Locale.US); 281 } 282 MacroDef.TemplateElement templateElement = 283 (MacroDef.TemplateElement) getNsElements().get(tag); 284 if (templateElement == null) { 285 UnknownElement child = copy(unknownElement); 286 rc.addChild(child.getWrapper()); 287 ret.addChild(child); 288 } else if (templateElement.isImplicit()) { 289 if (unknownElements.size() == 0 && !templateElement.isOptional()) { 290 throw new BuildException( 291 "Missing nested elements for implicit element " 292 + templateElement.getName()); 293 } 294 for (Iterator i = unknownElements.iterator(); 295 i.hasNext();) { 296 UnknownElement child = copy((UnknownElement) i.next()); 297 rc.addChild(child.getWrapper()); 298 ret.addChild(child); 299 } 300 } else { 301 UnknownElement presentElement = 302 (UnknownElement) presentElements.get(tag); 303 if (presentElement == null) { 304 if (!templateElement.isOptional()) { 305 throw new BuildException( 306 "Required nested element " 307 + templateElement.getName() + " missing"); 308 } 309 continue; 310 } 311 String presentText = 312 presentElement.getWrapper().getText().toString(); 313 if (!"".equals(presentText)) { 314 rc.addText(macroSubs(presentText, localAttributes)); 315 } 316 List list = presentElement.getChildren(); 317 if (list != null) { 318 for (Iterator i = list.iterator(); 319 i.hasNext();) { 320 UnknownElement child = copy((UnknownElement) i.next()); 321 rc.addChild(child.getWrapper()); 322 ret.addChild(child); 323 } 324 } 325 } 326 } 327 return ret; 328 } 329 330 336 public void execute() { 337 presentElements = new HashMap (); 338 getNsElements(); 339 processTasks(); 340 localAttributes = new Hashtable (); 341 Set copyKeys = new HashSet (map.keySet()); 342 for (Iterator i = macroDef.getAttributes().iterator(); i.hasNext();) { 343 MacroDef.Attribute attribute = (MacroDef.Attribute) i.next(); 344 String value = (String ) map.get(attribute.getName()); 345 if (value == null && "description".equals(attribute.getName())) { 346 value = getDescription(); 347 } 348 if (value == null) { 349 value = attribute.getDefault(); 350 value = macroSubs(value, localAttributes); 351 } 352 if (value == null) { 353 throw new BuildException( 354 "required attribute " + attribute.getName() + " not set"); 355 } 356 localAttributes.put(attribute.getName(), value); 357 copyKeys.remove(attribute.getName()); 358 } 359 if (copyKeys.contains("id")) { 360 copyKeys.remove("id"); 361 } 362 if (macroDef.getText() != null) { 363 if (text == null) { 364 if (!macroDef.getText().getOptional()) { 365 throw new BuildException( 366 "required text missing"); 367 } 368 text = ""; 369 } 370 if (macroDef.getText().getTrim()) { 371 text = text.trim(); 372 } 373 localAttributes.put(macroDef.getText().getName(), text); 374 } else { 375 if (text != null && !text.trim().equals("")) { 376 throw new BuildException( 377 "The \"" + getTaskName() + "\" macro does not support" 378 + " nested text data."); 379 } 380 } 381 if (copyKeys.size() != 0) { 382 throw new BuildException( 383 "Unknown attribute" + (copyKeys.size() > 1 ? "s " : " ") 384 + copyKeys); 385 } 386 387 UnknownElement c = copy(macroDef.getNestedTask()); 389 c.init(); 390 try { 391 c.perform(); 392 } catch (BuildException ex) { 393 if (macroDef.getBackTrace()) { 394 throw ProjectHelper.addLocationToBuildException( 395 ex, getLocation()); 396 } else { 397 ex.setLocation(getLocation()); 398 throw ex; 399 } 400 } finally { 401 presentElements = null; 402 localAttributes = null; 403 } 404 } 405 } 406 | Popular Tags |