58
58
59
59
import java .util .Enumeration ;
60
60
import java .util .Hashtable ;
61
+ import java .util .HashSet ;
61
62
import java .util .Iterator ;
62
63
import java .util .Properties ;
64
+ import java .util .Set ;
65
+ import java .util .Stack ;
63
66
64
67
import java .util .Vector ;
65
68
import java .io .InputStream ;
66
69
import java .io .IOException ;
67
70
import java .lang .reflect .Modifier ;
68
71
72
+ import org .apache .tools .ant .taskdefs .Typedef ;
73
+
69
74
/**
70
75
* Component creation and configuration.
71
76
*
@@ -98,6 +103,17 @@ public class ComponentHelper {
98
103
/** flag to rebuild typeClassDefinitions */
99
104
private boolean rebuildTypeClassDefinitions = true ;
100
105
106
+ /** Set of namespaces that have been checked for antlibs */
107
+ private Set checkedNamespaces = new HashSet ();
108
+
109
+ /**
110
+ * Stack of antlib contexts used to resolve definitions while
111
+ * processing antlib
112
+ */
113
+ private Stack antLibStack = new Stack ();
114
+ /** current antlib context */
115
+ private AntTypeTable antLibTypeTable = null ;
116
+
101
117
/**
102
118
* Map from task names to vectors of created tasks
103
119
* (String to Vector of Task). This is used to invalidate tasks if
@@ -175,32 +191,38 @@ public void initSubProject(ComponentHelper helper) {
175
191
AntTypeDefinition def = (AntTypeDefinition ) i .next ();
176
192
antTypeTable .put (def .getName (), def );
177
193
}
194
+ // add the parsed namespaces of the parent project
195
+ checkedNamespaces .add (helper .checkedNamespaces );
178
196
}
179
197
180
198
/** Factory method to create the components.
181
199
*
182
200
* This should be called by UnknownElement.
183
201
*
184
- * @param ue The component helper has access via ue to the entire XML tree.
185
- * @param ns Namespace. Also available as ue.getNamespace()
186
- * @param taskName The element name. Also available as ue.getTag()
202
+ * @param ue The Unknown Element creating this component
203
+ * @param ns Namespace URI. Also available as ue.getNamespace()
204
+ * @param componentType The component type,
205
+ * Also available as ue.getComponentName()
187
206
* @return the created component
188
207
* @throws BuildException if an error occuries
189
208
*/
190
209
public Object createComponent (UnknownElement ue ,
191
210
String ns ,
192
- String taskName )
211
+ String componentType )
193
212
throws BuildException {
194
- Object component = createComponent (taskName );
213
+ Object component = createComponent (componentType );
195
214
if (component == null ) {
196
215
return null ;
197
216
}
198
217
199
218
if (component instanceof Task ) {
200
219
Task task = (Task ) component ;
201
- task .setTaskType (taskName );
202
- task .setTaskName (taskName );
203
- addCreatedTask (taskName , task );
220
+ task .setLocation (ue .getLocation ());
221
+ task .setTaskType (componentType );
222
+ task .setTaskName (ue .getTaskName ());
223
+ task .setOwningTarget (ue .getOwningTarget ());
224
+ task .init ();
225
+ addCreatedTask (componentType , task );
204
226
}
205
227
206
228
return component ;
@@ -215,7 +237,11 @@ public Object createComponent(UnknownElement ue,
215
237
* @return the class if found or null if not.
216
238
*/
217
239
public Object createComponent (String componentName ) {
218
- return antTypeTable .create (componentName );
240
+ AntTypeDefinition def = getDefinition (componentName );
241
+ if (def == null ) {
242
+ return null ;
243
+ }
244
+ return def .create (project );
219
245
}
220
246
221
247
/**
@@ -227,7 +253,11 @@ public Object createComponent(String componentName) {
227
253
* @return the class if found or null if not.
228
254
*/
229
255
public Class getComponentClass (String componentName ) {
230
- return antTypeTable .getExposedClass (componentName );
256
+ AntTypeDefinition def = getDefinition (componentName );
257
+ if (def == null ) {
258
+ return null ;
259
+ }
260
+ return def .getExposedClass (project );
231
261
}
232
262
233
263
/**
@@ -236,7 +266,15 @@ public Class getComponentClass(String componentName) {
236
266
* @return the ant definition or null if not present
237
267
*/
238
268
public AntTypeDefinition getDefinition (String componentName ) {
239
- return antTypeTable .getDefinition (componentName );
269
+ checkNamespace (componentName );
270
+ AntTypeDefinition ret = null ;
271
+ if (antLibTypeTable != null && componentName .indexOf (':' ) == -1 ) {
272
+ ret = antLibTypeTable .getDefinition (componentName );
273
+ }
274
+ if (ret == null ) {
275
+ ret = antTypeTable .getDefinition (componentName );
276
+ }
277
+ return ret ;
240
278
}
241
279
242
280
/**
@@ -474,15 +512,15 @@ public Task createTask(String taskType) throws BuildException {
474
512
* creation fails.
475
513
*/
476
514
private Task createNewTask (String taskType ) throws BuildException {
477
- Class c = antTypeTable . getExposedClass (taskType );
515
+ Class c = getComponentClass (taskType );
478
516
if (c == null ) {
479
517
return null ;
480
518
}
481
519
482
520
if (!(Task .class .isAssignableFrom (c ))) {
483
521
return null ;
484
522
}
485
- Task task = (Task ) antTypeTable . create (taskType );
523
+ Task task = (Task ) createComponent (taskType );
486
524
if (task == null ) {
487
525
return null ;
488
526
}
@@ -557,7 +595,7 @@ private void invalidateCreatedTasks(String type) {
557
595
* instance creation fails.
558
596
*/
559
597
public Object createDataType (String typeName ) throws BuildException {
560
- return antTypeTable . create (typeName );
598
+ return createComponent (typeName );
561
599
}
562
600
563
601
/**
@@ -660,6 +698,31 @@ private void updateDataTypeDefinition(AntTypeDefinition def) {
660
698
project .log (" +Datatype " + name + " " + def .getClassName (),
661
699
Project .MSG_DEBUG );
662
700
antTypeTable .put (name , def );
701
+
702
+ if (antLibTypeTable != null && name .lastIndexOf (':' ) != -1 ) {
703
+ String baseName = name .substring (name .lastIndexOf (':' ) + 1 );
704
+ antLibTypeTable .put (baseName , def );
705
+ }
706
+ }
707
+ }
708
+
709
+ /**
710
+ * Called at the start of processing an antlib
711
+ */
712
+ public void enterAntLib () {
713
+ antLibTypeTable = new AntTypeTable (project );
714
+ antLibStack .push (antLibTypeTable );
715
+ }
716
+
717
+ /**
718
+ * Called at the end of processing an antlib
719
+ */
720
+ public void exitAntLib () {
721
+ antLibStack .pop ();
722
+ if (antLibStack .size () != 0 ) {
723
+ antLibTypeTable = (AntTypeTable ) antLibStack .peek ();
724
+ } else {
725
+ antLibTypeTable = null ;
663
726
}
664
727
}
665
728
@@ -751,6 +814,35 @@ private void initTypes() {
751
814
}
752
815
}
753
816
817
+ /**
818
+ * called for each component name, check if the
819
+ * associated URI has been examined for antlibs.
820
+ */
821
+ private void checkNamespace (String componentName ) {
822
+ if (componentName .indexOf (':' ) == -1 ) {
823
+ return ; // not a namespaced name
824
+ }
825
+
826
+ String uri = ProjectHelper .extractUriFromComponentName (componentName );
827
+ if (!uri .startsWith (ProjectHelper .ANTLIB_URI )) {
828
+ return ; // namespace that does not contain antlib
829
+ }
830
+ if (checkedNamespaces .contains (uri )) {
831
+ return ; // Alreay processed
832
+ }
833
+ checkedNamespaces .add (uri );
834
+ Typedef definer = new Typedef ();
835
+ definer .setProject (project );
836
+ definer .setURI (uri );
837
+ definer .setResource (
838
+ uri .substring ("antlib:" .length ()).replace ('.' , '/' )
839
+ + "/antlib.xml" );
840
+ // a fishing expedition :- ignore errors if antlib not present
841
+ definer .setOnError (new Typedef .OnError ("ignore" ));
842
+ definer .init ();
843
+ definer .execute ();
844
+ }
845
+
754
846
/**
755
847
* map that contains the component definitions
756
848
*/
0 commit comments