File: integration-guide.html

package info (click to toggle)
axis 1.4-25
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 51,864 kB
  • sloc: java: 129,119; xml: 10,573; jsp: 983; sh: 84; cs: 36; makefile: 26
file content (1340 lines) | stat: -rw-r--r-- 50,029 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <title>Axis System Integration Guide</title>
<link href="axis.css" rel=stylesheet type=text/css>
</head>
<body text="#000000" bgcolor="#FFFFFF">

<center>
<h1>
<img SRC="images/axis.jpg" height=96 width=176></h1></center>

<h1>
Axis System Integration Guide</h1>
<i>1.2 Version</i>
<br><i>Feedback: <a href="mailto:axis-dev@ws.apache.org">axis-dev@ws.apache.org</a></i>
<h3>
Table of Contents</h3>
<a href="#Introduction">Introduction</a>
<br><a href="#Pluggable APIs">Pluggable APIs</a>
<br>&nbsp; <a href="#Components">Components</a>
<!-- <br>&nbsp; <a href="#System Management Plug">System Management</a>
-->
<br>&nbsp; <a href="#Logging/Tracing Plug">Logging/Tracing</a>
<br>&nbsp; <a href="#Configuration Plug">Configuration</a>
<br>&nbsp; <a href="#Handlers Plug">Handlers</a>
<br>&nbsp; <a href="#Internationalization Plug">Internationalization</a>
<br>&nbsp; <a href="#Performance Monitoring Plug">Performance Monitoring</a>
<br>&nbsp; <a href="#Encoding Plug">Encoding</a>
<br>&nbsp; <a href="#WSDL plug">WSDL Parser and Code Generator Framework</a>
<br><a href="#Client SSL">Client SSL</a>

<h2>
<a NAME="Introduction"></a>Introduction</h2>
The primary purpose of this guide is
to present how Axis can be integrated into an existing web application
server, such as Tomcat or WebSphere, for example.&nbsp; Axis has a number
of Pluggable APIs that are necessary for such an integration.
<p>
The reader may find useful background information in the
<a href="architecture-guide.html">Architecture Guide</a>.

<h2>
<a NAME="Pluggable APIs"></a>Pluggable APIs</h2>
The following are the points that are pluggable in order to integrate Axis
into a web application server.
The first subsection details a number of pluggable components in general.
More details are provided for other components in the remaining
subsections.

<h3>
<a NAME="Components"></a>Components</h3>
This section describes in general how to plug specializations
of various components into Axis.

<h4>
General Strategy
</h4>
To override the default behavior for a pluggable component:
<ul>
<li>Develop implementation of components interface</li>
<br>&nbsp;
<li>Define the implementation class to Axis by either creating
a service definition file (prefered)
or by setting a system property.
<ul>
<br>
<li><strong>PREFERED:</strong> To create a service definition file:</li>
<ul>
<li>The name of the service definition file is derived from the interface
or abstract class which the service implements/extends:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>/META-INF/services/&lt;componentPackage&gt;.&lt;interfaceName&gt;</code>.</li>
<li>Put the fully qualified class name of the implementation class on a line by itself
in the service definition file.</li>
</ul>
<br>
<li>Set system property:
<ul>
<li>The name of the system property is the name of the interface.</li>
<li>The value of the system property is the name of the implementation.</li>
<li>The optional system property name (in table, below) may be also be used.</li>
<br>&nbsp;
<li>Setting a system property is not prefered, particularly in a J2EE or other application
hosting environment, because it imposes a directive across all applications.
This may or may not be appropriate behavior.
If it is to be done, it should never be done from within a Web Application at runtime.
</li>
</ul>
</li>
</ul>
<br>
<li>Package the implementation class and, if used,
the service definition file in a JAR file
and/or place it where it can be picked up by a class loader (CLASSPATH).</li>
</ul>

<h4>
Example 1
</h4>
To override the default behavior for the Java Compiler:
<ul>
<li>An implementation of the <code>Compiler</code> interface is already provided for the <code>Jikes</code> compiler.</li>
<br>&nbsp;
<li>Create the service definition file named:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>/META-INF/services/org.apache.axis.components.compiler.Compiler</code></li>
<br>&nbsp;
<li>Add the following line to the service definition file:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>org.apache.axis.components.compiler.Jikes</code></li>
<br>&nbsp;
<li>Since <code>org.apache.axis.components.compiler.Jikes</code>
is packaged with Axis, all that needs to be done is to ensure
that the service definition file is loadable by a class loader.
</li>
</ul>

<h4>
Example 2
</h4>
To override the default behavior for the SocketFactory
in an environment that does not allow resources to be
located/loaded appropriately, or where the behavior
needs to be forced to a specific implementation:
<ul>
<li>Provide an implementation of the <code>SocketFactory</code> interface,
for example <code>your.package.YourSocketFactory</code></li>
<br>&nbsp;
<li>Set the system property named
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>org.apache.axis.components.net.SocketFactory</code>
<br>
to the value
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>your.package.YourSocketFactory</code>
<br>
<p>This can be done by using the JVM commandline
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<code>-Dorg.apache.axis.components.net.SocketFactory=your.package.YourSocketFactory</code>
<br>&nbsp;
</li>
<li>Ensure that the implementation class is loadable by a class loader.
</li>
</ul>

<h4>
Reference
</h4>

<table border="1">
<tr>
<th>Component/Package</th>
<th>Factory</th>
<th>Interface</th>
<th>Optional System Property</th>
<th>Default Implementation</th>
</tr>
<tr>
<td><code>org.apache.axis.components.compiler</code></td>
<td><code>CompilerFactory.getCompiler()</code></td>
<td><code>Compiler</code></td>
<td><code>axis.Compiler</code></td>
<td><code>Javac</code></td>
</tr>
<tr>
<td><code>org.apache.axis.components.image</code></td>
<td><code>ImageIOFactory.getImageIO()</code></td>
<td><code>ImageIO</code></td>
<td><code>axis.ImageIO</code></td>
<td><code>MerlinIO, JimiIO, JDK13IO</code></td>
</tr>
<tr>
<td><code>org.apache.axis.components.jms</code></td>
<td><code>JMSVendorAdapterFactory.getJMSVendorAdapter()</code></td>
<td><code>JMSVendorAdapter</code></td>
<td><code></code></td>
<td><code>JNDIVendorAdapter</code></td>
</tr>
<tr>
<td><code>org.apache.axis.components.net</code></td>
<td><code>SocketFactoryFactory.getFactory()</code></td>
<td><code>SocketFactory</code></td>
<td><code>axis.socketFactory</code></td>
<td><code>DefaultSocketFactory</code></td>
</tr>
<tr>
<td><code>org.apache.axis.components.net</code></td>
<td><code>SocketFactoryFactory.getSecureFactory()</code></td>
<td><code>SecureSocketFactory</code></td>
<td><code>axis.socketSecureFactory</code></td>
<td><code>JSSESocketFactory</code></td>
</tr>
</table>

<!--
<h3>
<a NAME="System Management Plug"></a>System Management</h3>
What points are necessary to manage Axis?
<ul>
<li>
Justification/Rationale - why is this plug point necessary?&nbsp; Spec
compliance?</li>

<li>
Interfaces</li>

<li>
Mechanism</li>

<ul>
<li>
Life cycle</li>

<li>
Exception handling - in general; plug-in shouldn't throw any exceptions
- does runtime ignore? Log?)</li>

<li>
Multiple thread support?&nbsp; Ie., is synchronization required?</li>
</ul>

<li>
Configuration/reconfiguration</li>

<li>
Default behavior if not plugged.</li>

<li>
Example</li>
</ul>
-->

<h3><a NAME="Logging/Tracing Plug"></a>Logging/Tracing</h3>
Axis logging and tracing is based on the Logging component of the
<a href="http://jakarta.apache.org/commons/index.html">Jakarta Commons</a>
project, or the Jakarta Commons Logging (JCL) SPI.
The JCL provides a Log interface with thin-wrapper implementations for
other logging tools, including
<a href="http://jakarta.apache.org/log4j/docs/index.html">Log4J</a>,
<a href="http://jakarta.apache.org/avalon/logkit/index.html">Avalon LogKit</a>,
and
<a>JDK 1.4</a>.
The interface maps closely to Log4J and LogKit.

<h4>Justification/Rationale</h4>
A pluggable logging/trace facility enables
Axis to direct logging/trace messages to a host web application server's
logging facility.
A central logging facility with a single point of configuration/control
is superior to distinct logging mechanisms for each of a multitude of
middleware components that are to be integrated into
a web application server.

<h4>Integration</h4>
The minimum requirement to integrate with another logger
is to provide an implementation of the
<code>org.apache.commons.logging.Log</code> interface.
In addition, an implementation of the
<code>org.apache.commons.logging.LogFactory</code> interface
can be provided to meet
specific requirements for connecting to, or instantiating, a logger.
<ul>
<li><h5>org.apache.commons.logging.Log</h5></li>
The <code>Log</code> interface defines the following methods for use
in writing log/trace messages to the log:
<ul>
<code>
<br>log.fatal(Object message);
<br>log.fatal(Object message, Throwable t);
<br>log.error(Object message);
<br>log.error(Object message, Throwable t);
<br>log.warn(Object message);
<br>log.warn(Object message, Throwable t);
<br>log.info(Object message);
<br>log.info(Object message, Throwable t);
<br>log.debug(Object message);
<br>log.debug(Object message, Throwable t);
<br>log.trace(Object message);
<br>log.trace(Object message, Throwable t);
<br>&nbsp;
<br>log.isFatalEnabled();
<br>log.isErrorEnabled();
<br>log.isWarnEnabled();
<br>log.isInfoEnabled();
<br>log.isDebugEnabled();
<br>log.isTraceEnabled();
<br>
</code>
</ul>
<p>
Semantics for these methods are such that it is expected
that the severity of messages is ordered, from highest to lowest:
<p>
<ul>
<li>fatal - Consider logging to console and system log.</li>
<li>error - Consider logging to console and system log.</li>
<li>warn - Consider logging to console and system log.</li>
<li>info - Consider logging to console and system log.</li>
<li>debug - Log to system log, if enabled.</li>
<li>trace - Log to system log, if enabled.</li>
</ul>

<br>&nbsp;
<li><h5>org.apache.commons.logging.LogFactory</h5></li>
If desired, the default implementation of the
<code>org.apache.commons.logging.LogFactory</code>
interface can be overridden,
allowing the JDK 1.3 Service Provider discovery process
to locate and create a LogFactory specific to the needs of the application.
Review the Javadoc for the <code>LogFactoryImpl.java</code>
for details.
</ul>

<h4>Mechanism</h4>
<ul>
<li><h5>Life cycle</h5></li>
The JCL LogFactory implementation must assume responsibility for
either connecting/disconnecting to a logging toolkit,
or instantiating/initializing/destroying a logging toolkit.
<br>&nbsp;
<li><h5>Exception handling</h5></li>
The JCL Log interface doesn't specify any exceptions to be handled,
the implementation must catch any exceptions.
<br>&nbsp;
<li><h5>Multiple threads</h5></li>
The JCL Log and LogFactory implementations must ensure
that any synchronization required by the logging toolkit
is met.
</ul>

<h4>Logger Configuration</h4>
<ul>
<li><h5>Log</h5></li>
The default <code>LogFactory</code> provided by JCL
can be configured to instantiate a specific implementation of the
<code>org.apache.commons.logging.Log</code> interface
by setting the property <code>org.apache.commons.logging.Log</code>.
This property can be specified as a system property,
or in the <code>commons-logging.properties</code> file,
which must exist in the CLASSPATH.
<br>&nbsp;
<li><h5>Default logger if not plugged</h5></li>
The Jakarta Commons Logging SPI uses the
implementation of the <code>org.apache.commons.logging.Log</code>
interface specified by the system property
<code>org.apache.commons.logging.Log</code>.
If the property is not specified or the class is not available then the JCL
provides access to a default logging toolkit by searching the CLASSPATH
for the following toolkits, in order of preference:
<ul>
<li><a href="http://jakarta.apache.org/log4j/docs/index.html">Log4J</a></li>
<li>JDK 1.4</li>
<li>JCL SimpleLog</li>
</ul>
</ul>

<h3>
<a NAME="Configuration Plug"></a>Configuration</h3>
<br>The internal data model used by Axis is based on
an Axis specific data model: Web Services Deployment Descriptor (WSDD).
Axis initially obtains the WSDD information for a
service from an instance of <code>org.apache.axis.EngineConfiguration</code>.

<p>The EngineConfiguration is provided by an implementation of
the interface <code>org.apache.axis.EngineConfigurationFactory</code>,
which currently provides methods that return client and server
configurations.

<p>Our focus will be how to define the implementation class for
<code>EngineConfigurationFactory</code>.

<ul>
<li>
Justification/Rationale</li>
<br>While the default behaviour is sufficient for general use of
Axis, integrating Axis into an existing application server may
require an alternate deployment model.
A customized implementation of the EngineConfigurationFactory
would map from the hosts deployment model to Axis's internal
deployment model.
<br>&nbsp;

<li>
Mechanism</li>
<br>The relevant sequence of instructions used to obtain
configuration information and initialize Axis is as follows:
<ul>
<br>
<code>EngineConfigurationFactory factory = EngineConfigurationFactoryFinder(someContext);</code>
<br>
<code>EngineCongfiguration config = factory.getClientEngineConfig();</code>
<br>
<code>AxisClient = new AxisClient(config);</code>
</ul>
<br>The details may vary (server versus client, whether other factories are involved, etc).
Regardless, the point is that integration code is responsible for
calling <code>EngineConfigurationFactoryFinder(someContext)</code>
and ensuring that the results are handed to Axis.&nbsp;
<code>someContext</code> is key to how the factory finder
locates the appropariate implementation of
EngineConfigurationFactory to be used, if any.

<p>EngineConfigurationFactoryFinder works as follows:
<br>&nbsp;
<ul>
<li>Obtain a list of classes that implement
<code>org.apache.axis.EngineConfigurationFactory</code>,
in the following order:
<ul>
<li>
The value of the system property <code>axis.EngineConfigFactory</code>.
</li>
<li>
The value of the system property
<code>org.apache.axis.EngineConfigurationFactory</code>.
</li>
<li>Locate all resources named
<code>META-INF/services/org.apache.axis.EngineConfigurationFactory</code>.
Each line of such a resource identifies the name of a class
implementing the interface ('#' comments, through end-of-line).
</li>
<li>
<code>org.apache.axis.configuration.EngineConfigurationFactoryServlet</code>
</li>
<li>
<code>org.apache.axis.configuration.EngineConfigurationFactoryDefault</code>
</li>
</ul>
</li>

<br>
<li>Classes implementing EngineConfigurationFactory are required to
provide the method
<br>&nbsp;
<ul>
<code>public static EngineConfigurationFactory newFactory(Object)</code>
</ul>
<br>
This method is called, passing <code>someContext</code> as the parameter.
</li>

<br>&nbsp;
<li>
The <code>newFactory</code> method 
is required to check the <code>someContext</code> parameter to determine if
it is meaningfull to the class (at a minimum,
verify that it is of an expected type, or class)
and may, in addition, examine the overall runtime environment.
If the environment can provide information required by
an EngineConfigurationFactory,
then the <code>newFactory()</code> may return in instance of that factory.
Otherwise, <code>newFactory()</code> must return null.
</li>

<br>&nbsp;
<li>
EngineConfigurationFactoryFinder returns the first non-null
factory it obtains.
</li>
</ul>
<br>&nbsp;


<li>
Default behavior</li>
<br>The default behaviour is provided by the last two elements
of the list of implementing classes, as described above:
<ul>
<li>
<code>org.apache.axis.configuration.EngineConfigurationFactoryServlet</code>
<br><code>newFactory(obj)</code> is called.
If <code>obj instanceof javax.servlet.ServletContext</code> is true,
then an instance of this class is returned.
<p>The default Servlet factory is expected to function as a server
(as a client it will incorrectly attempt
to load the WSDD file <code>client-config.wsdd</code>
from the current working directory!).

<p>The default Servlet factory will open the Web Application resource
<code>/WEB-INF/server-config.wsdd</code>
(The name of this file may be changed using the
system property <code>axis.ServerConfigFile</code>):
<ul>
<li>
If it exists as an accessible file (i.e. not in a JAR/WAR file),
then it opens it as a file.
This allows changes to be saved,
if changes are allowed & made using the Admin tools.
</li>
<li>
If it does not exist as a file, then an attempt is made
to access it as a resource stream (getResourceAsStream),
which works for JAR/WAR file contents.
</li>
<li>
If the resource is simply not available,
an attempt is made to create it as a file.
</li>
<li>
If all above attempts fail, a final attempt is
made to access <code>org.apache.axis.server.server-config.wsdd</code>
as a data stream.
</li>
</ul>

</li>
<br>&nbsp;
<li>
<code>org.apache.axis.configuration.EngineConfigurationFactoryDefault</code>
<br><code>newFactory(obj)</code> is called.
If <code>obj</code> is null
then an instance of this class is returned.
A non-null <code>obj</code> is presumed to
require a non-default factory.

<p>The default factory will load the WSDD files
<code>client-config.wsdd</code> or <code>server-config.wsdd</code>,
as appropriate, from the current working directory.
The names of these files may be changed using the
system properties <code>axis.ClientConfigFile</code>
and <code>axis.ServerConfigFile</code>,
respectively.
</li>
</ul>

</ul>

<h3>
<a NAME="Handlers Plug"></a>Handlers</h3>
See the <a href="architecture-guide.html">Architecture 
Guide</a> for current information on Handlers.

<h3>
<a NAME="Internationalization Plug"></a>Internationalization</h3>
Axis supports internationalization by providing
both a property file of the strings used in Axis,
and an extension mechanism that facilitates
accessing internal Axis messages and extending the messages
available to integration code based on existing Axis code.

<h4>
<a NAME="Translation"></a>Translation</h4>

<ul>
<li>
Justification/Rationale</li>

<br>
In order for readers of languages other than English
to be comfortable with Axis,
we provide a mechanism for the strings used in Axis to be translated.
We do not provide any translations in Axis;
we merely provide a means by which translators
can easily plug in their translations.
<br>&nbsp;

<li>
Mechanism</li>
<br>
Axis provides english messages in the
Java resource named
org.apache.axis.i18n.resource.properties
(in the source tree, the file is named
xml-axis/java/src/org/apache/axis/i18n/resource.properties).

<p>Axis makes use of the Java internationalization mechanism -
i.e., a java.util.ResourceBundle backed by a properties file -
and the java.text.MessageFormat class to substitute
parameters into the message text.

<ul>
<br>
<li>
java.util.ResourceBundle retrieves message text
from a property file using a key provided by the program.
Entries in a message resource file are of the form
&lt;key&gt;=&lt;message&gt;.
</li>

<br>&nbsp;
<li>
java.text.MessageFormat substitutes variables for
markers in the message text.
Markers use the syntax
<font face="Courier New,Courier">"{X}"</font>
where <code>X</code> is
the number of the variable, starting at 0.
</li>
</ul>

<p>For example: <code>myMsg00=My {0} is {1}.</code>

<p>Translation requires creating an
alternate version of the property file provided by Axis
for a target language.
The JavaDoc for <code>java.utils.ResourceBundle</code>
provides details on how to identify different property
files for different locales.

<p>For details on using Axis's internationalization tools,
see the <a href="developers-guide.html">Developer's Guide</a>.
<br>&nbsp;

<li>
Default behavior</li>

<br>The default behavior, meaning what happens when a translated file doesn't
exist for a given locale, is to fall back on the English-language properties
file.&nbsp; If that file doesn't exist (unlikely unless something is seriously
wrong), Axis will throw an exception with an English-language reason message.
<br>&nbsp;
</ul>

<h4>
<a NAME="Extending Message Files"></a>Extending Message Files</h4>
Axis provides a Message file extension mechanism
that allows Axis-based code to use Axis message keys,
as well as new message keys unique to the extended code.

<ul>
<li>
Justification/Rationale</li>
<br>
Axis provides pluggable interfaces for
various Axis entities, including EngineConfigurationFactory's,
Provides, and Handlers.
Axis also provides a variety of implementations
of these entities.
It is convenient to use Axis source code for
such implementations as starting points for developing
extentions and customizations that fulfill the unique needs
of the end user.
<br>&nbsp;

<li>
Procedure</li>
<br>To extend the Axis message file:
<br>&nbsp;
<ul>
<li>Copy the Axis source file
<code>java/src/org/apache/axis/i18n/Messages.java</code>
to your project/package, say
<code>my/project/package/path/Messages.java</code>.
</li>
<ul>
<li>Set the <code>package</code> declaration in the copied file
to the correct package name.
</li>
<li>Set the private attribute <code>projectName</code>
to <code>"my.project"</code>:
the portion of the package name that is common to your project.
<code>projectName</code> must be equal to or be a prefix of the
copied Messages package name.
</li>
</ul>
<br>&nbsp;
<li>Create the file
<code>my/project/package/path/resource.properties</code>.
Add new message key/value pairs to this file.
</li>
<br>&nbsp;
<li>As you copy Axis source files over to your project,
change the <code>import org.apache.axis.i18n.Messages</code>
statement to <code>import my.project.package.path.Messages</code>.
</li>
<li>Use the methods provided by the class Messages,
as discussed in the <a href="developers-guide.html">Developer's Guide</a>,
to access the new messages.
</li>
</ul>
<br>

<li>
Behavior</li>

<ul>
<li>
Local Search</li>
<br><code>Messages</code> begins looking for a key's value in
the <code>resources.properties</code>
resource in it's (Messages) package.
<br>&nbsp;

<li>
Hierarchical Search</li>
<br>If <code>Messages</code> cannot locate
either the key, or the resource file,
it walks up the package hierarchy until it finds it.
The top of the hierarchy, above which it will not search,
is defined by the <code>projectName</code> attribute,
set above.
<br>&nbsp;

<li>
Default behavior</li>
<br>If the key cannot be found in the package hierarchy
then a default resource is used.
The default behaviour is determined by
the <code>parent</code> attribute of the
<code>Messages</code> class copied to your extensions directory.
<p>Unless changed, the default behavior, meaning what happens when a key
isn't defined in the new properties file,
is to fall back to the Axis properties file
(org.apache.axis.i18n.resource.properties).
<br>&nbsp;
</ul>
</ul>

<h3>
<a NAME="Performance Monitoring Plug"></a>Performance Monitoring</h3>
Axis does not yet include specific Performance Monitoring Plugs.
<!--
<ul>
<li>
Justification/Rationale - why is this plug point necessary?&nbsp; Spec
compliance?</li>

<li>
Interfaces</li>

<li>
Mechanism</li>

<ul>
<li>
Life cycle</li>

<li>
Exception handling - in general; plug-in shouldn't throw any exceptions
- does runtime ignore? Log?)</li>

<li>
Multiple thread support?&nbsp; Ie., is synchronization required?</li>
</ul>

<li>
Configuration/reconfiguration</li>

<li>
Default behavior if not plugged.</li>

<li>
Example</li>
</ul>
-->

<h3>
<a NAME="Encoding Plug"></a>Encoding</h3>
Axis does not yet include an Encoding Plug.
<!--
How can a system integrator plug in other encoding mechanisms such as SOAP
1.2 or optimized XML-based encoding?
<ul>
<li>
Justification/Rationale - why is this plug point necessary?&nbsp; Spec
compliance?</li>

<li>
Interfaces</li>

<li>
Mechanism</li>

<ul>
<li>
Life cycle</li>

<li>
Exception handling - in general; plug-in shouldn't throw any exceptions
- does runtime ignore? Log?)</li>

<li>
Multiple thread support?&nbsp; Ie., is synchronization required?</li>
</ul>

<li>
Configuration/reconfiguration</li>

<li>
Default behavior if not plugged.</li>

<li>
Example</li>
</ul>
-->

<h3>
<a NAME="WSDL plug"></a>WSDL Parser and Code Generator Framework</h3>
WSDL2Java is Axis's tool to generate Java artifacts from WSDL.&nbsp; This
tool is extensible.&nbsp; If users of Axis wish to extend Axis, then they
may also need to extend or change the generated artifacts.&nbsp; For example,
if Axis is inserted into some product which has an existing deployment
model that's different than Axis's deployment model, then that product's
version of WSDL2Java will be required to generate deployment descriptors
other than Axis's deploy.wsdd.
<p>What follows immediately is a description of the framework.&nbsp; If
you would rather dive down into the dirt of <a href="#WSDL Examples">examples</a>,
you could learn a good deal just from them.&nbsp; Then you could come back
up here and learn the gory details.
<p>There are three parts to WSDL2Java:
<ol>
<li>
The symbol table</li>

<li>
The parser front end with a generator framework</li>

<li>
The code generator back end (WSDL2Java itself)</li>
</ol>

<h4>
Symbol Table</h4>
The symbol table, found in org.apache.axis.wsdl.symbolTable, will contain
all the symbols from a WSDL document, both the symbols from the WSDL constructs
themselves (portType, binding, etc), and also the XML schema types that
the WSDL refers to.
<p><font color="#FF0000">NOTE:&nbsp; Needs lots of description here.</font>
<p>The symbol table is not extensible, but you <b>can</b> add fields to
it by using the Dynamic Variables construct:
<ul>
<li>
You must have some constant object for a dynamic variable key.&nbsp; For
example:&nbsp; public static final String MY_KEY = "my key";</li>

<li>
You set the value of the variable in your GeneratorFactory.generatorPass:&nbsp;
entry.setDynamicVar(MY_KEY, myValue);</li>

<li>
You get the value of the variable in your generators:&nbsp; Object myValue
= entry.getDynamicVar(MY_KEY);</li>
</ul>

<h4>
Parser Front End and Generator Framework</h4>
The parser front end and generator framework is located in org.apache.axis.wsdl.gen.&nbsp;
The parser front end consists of two files:
<ul>
<li>
Parser</li>

<br><tt>public class Parser {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Parser();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public boolean isDebug();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setDebug(boolean);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public boolean isImports();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setImports(boolean);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public boolean isVerbose();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setVerbose(boolean);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public long getTimeout();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setTimeout(long);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public java.lang.String getUsername();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setUsername(java.lang.String);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public java.lang.String getPassword();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setPassword(java.lang.String);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public GeneratorFactory getFactory();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setFactory(GeneratorFactory);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public org.apache.axis.wsdl.symbolTable.SymbolTable
getSymbolTable();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public javax.wsdl.Definition getCurrentDefinition();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public java.lang.String getWSDLURI();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void run(String wsdl) throws java.lang.Exception;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void run(String context, org.w3c.dom.Document
wsdlDoc) throws java.io.IOException, javax.wsdl.WSDLException;</tt>
<br><tt>}</tt>
<p>The basic behavior of this class is simple:&nbsp; you instantiate a
Parser, then you run it.
<ul><tt>Parser parser = new Parser();</tt>
<br><tt>parser.run("myfile.wsdl");</tt></ul>

<p><br>There are various options on the parser that have accessor methods:
<ul>
<li>
debug - default is false - dump the symbol table after the WSDL file has
been parsed</li>

<li>
imports - default is true - should imported files be visited?</li>

<li>
verbose - default is false - list each file as it is being parsed</li>

<li>
timeout - default is 45 - the number of seconds to wait before halting
the parse</li>

<li>
username - no default - needed for protected URI's</li>

<li>
password - no default - needed for protected URI's</li>
</ul>

<p><br>Other miscellaneous methods on the parser:
<ul>
<li>
get/setFactory - get or set the GeneratorFactory on this parser - see below
for details.&nbsp; The default generator factory is NoopFactory, which
generates nothing.</li>

<li>
getSymbolTable - once a run method is called, the symbol table will be
populated and can get queried.</li>

<li>
getCurrentDefinition - once a run method is called, the parser will contain
a Definition object which represents the given wsdl file.&nbsp; Definition
is a WSDL4J object.</li>

<li>
getWSDLURI - once the run method which takes a string is called, the parser
will contain the string representing the location of the WSDL file.&nbsp;
Note that the other run method - run(String context, Document wsdlDoc)
- does not provide a location for the wsdl file.&nbsp; If this run method
is used, getWSDLURI will be null.</li>

<li>
There are two run methods.&nbsp; The first, as shown above, takes a URI
string which represents the location of the WSDL file.&nbsp; If you've
already parsed the WSDL file into an XML Document, then you can use the
second run method, which takes a context and the WSDL Document.</li>
</ul>

<p><br>An extension of this class would ...
<br><br>
<font color="#FF0000">NOTE:&nbsp; continue this sentiment...</font>
<br>&nbsp;
<li>
WSDL2</li>

<br>Parser is the programmatic interface into the WSDL parser.&nbsp; WSDL2
is the command line tool for the parser.&nbsp; It provides an extensible
framework for calling the Parser from the command line.&nbsp; It is named
WSDL2 because extensions of it will likely begin with WSDL2:&nbsp; <b>WSDL2</b>Java,
<b>WSDL2</b>Lisp, <b>WSDL2</b>XXX.
<p><tt>public class WSDL2 {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected WSDL2();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected Parser createParser();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected Parser getParser();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void addOptions(org.apache.axis.utils.CLOptionDescriptor[]);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void parseOption(org.apache.axis.utils.CLOption);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void validateOptions();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void printUsage();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void run(String[]);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public static void main(String[]);</tt>
<br><tt>}</tt>
<p>Like all good command line tools, it has a main method.&nbsp; Unlike
some command line tools, however, its methods are not static.&nbsp; Static
methods are not extensible.&nbsp; WSDL2's main method constructs an instance
of itself and calls methods on that instance rather than calling static
methods.&nbsp; These methods follow a behavior pattern.&nbsp; The main
method is very simple:
<br>&nbsp;
<ul><tt>&nbsp;&nbsp;&nbsp; public static void main(String[] args) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WSDL2 wsdl2 = new WSDL2();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wsdl2.run(args);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt></ul>

<p><br>The constructor calls createParser to construct a Parser or an extension
of Parser.
<p>run calls:
<ul>
<li>
parseOption to parse each command line option and call the appropriate
Parser accessor.&nbsp; For example, when this method parses --verbose,
it calls parser.setVerbose(true)</li>

<li>
validateOptions to make sure all the option values are consistent</li>

<li>
printUsage if the usage of the tool is in error</li>

<li>
parser.run(args);</li>
</ul>

<p><br>If an extension has additional options, then it is expected to call
addOptions before calling run.&nbsp; So extensions will call, as necessary,
getParser, addOptions, run.&nbsp; Extensions will override, as necessary,
createParser, parseOption, validateOptions, printUsage.
<br>&nbsp;
<p>The generator framework consists of 2 files:
<ul>
<li>
Generator</li>

<br>The Generator interface is very simple.&nbsp; It just defines a generate
method.
<p><tt>public interface Generator</tt>
<br><tt>{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void generate() throws java.io.IOException;</tt>
<br><tt>}</tt>
<br>&nbsp;
<li>
GeneratorFactory</li>

<p><br><tt>public interface GeneratorFactory</tt>
<br><tt>{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void generatorPass(javax.wsdl.Definition,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(javax.wsdl.Message,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(javax.wsdl.PortType,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(javax.wsdl.Binding,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(javax.wsdl.Service,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(TypeEntry, SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public Generator getGenerator(javax.wsdl.Definition,
SymbolTable);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setBaseTypeMapping(BaseTypeMapping);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public BaseTypeMapping getBaseTypeMapping();</tt>
<br><tt>}</tt>
<p>The GeneratorFactory interface defines a set of methods that the parser
uses to get generators.&nbsp; There should be a generator for each of the
WSDL constructs (message, portType, etc - note that these depend on the
WSDL4J classes:&nbsp; javax.xml.Message, javax.xml.PortType, etc); a generator
for schema types; and a generator for the WSDL Definition itself.&nbsp;
This last generator is used to generate anything that doesn't fit into
the previous categories
<p>In addition to the getGeneratorMethods, the GeneratorFactory defines
a generatorPass method which provides the factory implementation a chance
to walk through the symbol table to do any preprocessing before the actual
generation begins.
<p>Accessors for the base type mapping are also defined.&nbsp; These are
used to translate QNames to base types in the given target mapping.
<br>&nbsp;</ul>
In addition to Parser, WSDL2, Generator, and GeneratorFactory, the org.apache.axis.wsdl.gen
package also contains a couple of no-op classes:&nbsp; NoopGenerator and
NoopFactory.&nbsp; NoopGenerator is a convenience class for extensions
that do not need to generate artifacts for every WSDL construct.&nbsp;
For example, WSDL2Java does not generate anything for messages, therefore
its factory's getGenerator(Message, SymbolTable) method returns an instance
of NoopGenerator.&nbsp; NoopFactory returns a NoopGenerator for all getGenerator
methods.&nbsp; The default factory for Parser is the NoopFactory.</ul>

<h4>
Code Generator Back End</h4>
The meat of the WSDL2Java back end generators is in org.apache.axis.wsdl.toJava.&nbsp;
Emitter extends Parser.&nbsp; org.apache.axis.wsdl.WSDL2Java extends WSDL2.&nbsp;
JavaGeneratorFactory implements GeneratorFactory.&nbsp; And the various
JavaXXXWriter classes implement the Generator interface.
<p><font color="#FF0000">NOTE:&nbsp; Need lots more description here...</font>
<h4>
<a NAME="WSDL Examples"></a>WSDL Framework Extension Examples</h4>
Everything above sounds rather complex.&nbsp; It is, but that doesn't mean
your extension has to be.
<h5>
Example 1 - Simple extension of WSDL2Java - additional artifact</h5>
The simplest extension of the framework is one which generates everything
that WSDL2Java already generates, plus something new.&nbsp; Example 1 is
such an extension.&nbsp; It's extra artifact is a file for each service
that lists that service's ports.&nbsp; I don't know why you'd want to do
this, but it makes for a good, simple example.&nbsp; See samples/integrationGuide/example1
for the complete implementation of this example.
<br>&nbsp;
<ul>
<li>
First you must create your writer that writes the new artifact.&nbsp; This
new class extends org.apache.axis.wsdl.toJava.JavaWriter.&nbsp; JavaWriter
dictates behavior to its extensions; it calls writeFileHeader and writeFileBody.&nbsp;
Since we don't care about a file header for this example, writeFileHeader
is a no-op method.&nbsp; writeFileBody does the real work of this writer.</li>

<p><br><tt>public class MyListPortsWriter extends JavaWriter {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; private Service service;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public MyListPortsWriter(</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Emitter emitter,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ServiceEntry sEntry,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
SymbolTable symbolTable) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(emitter,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
new QName(</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sEntry.getQName().getNamespaceURI(),</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sEntry.getQName().getLocalPart() + "Lst"),</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"", "lst", "Generating service port list file", "service list");</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.service = sEntry.getService();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void writeFileHeader() throws IOException
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void writeFileBody() throws IOException
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map portMap = service.getPorts();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator portIterator
= portMap.values().iterator();</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (portIterator.hasNext())
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Port p = (Port) portIterator.next();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pw.println(p.getName());</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pw.close();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<br>&nbsp;
<li>
Then you need a main program.&nbsp; This main program extends WSDL2Java
so that it gets all the functionality of that tool.&nbsp; The main of this
tool does 3 things:</li>

<ul>
<li>
instantiates itself</li>

<li>
adds MyListPortsWriter to the list of generators for a WSDL service</li>

<li>
calls the run method.</li>
</ul>
That's it!&nbsp; The base tool does all the rest of the work.
<p><tt>public class MyWSDL2Java extends WSDL2Java {</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; public static void main(String args[]) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyWSDL2Java myWSDL2Java
= new MyWSDL2Java();</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JavaGeneratorFactory
factory =</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(JavaGeneratorFactory) myWSDL2Java.getParser().getFactory();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory.addGenerator(Service.class,
MyListPortsWriter.class);</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myWSDL2Java.run(args);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt></ul>

<h5>
Example 2 - Not quite as simple an extension of WSDL2Java - change an artifact</h5>
In this example, we'll replace deploy.wsdd with mydeploy.useless.&nbsp;
For brevity, mydeploy.useless is rather useless.&nbsp; Making it useful
is an exercise left to the reader.&nbsp; See samples/integrationGuide/example2
for the complete implementation of this example.
<ul>
<li>
First, here is the writer for the mydeploy.useless.&nbsp; This new class
extends org.apache.axis.wsdl.toJava.JavaWriter.&nbsp; JavaWriter dictates
behavior to its extensions; it calls writeFileHeader and writeFileBody.&nbsp;
Since we don't care about a file header for this example, writeFileHeader
is a no-op method.&nbsp; writeFileBody does the real work of this writer.&nbsp;
It simply writes a bit of a song, depending on user input.</li>

<p><br>Note that we've also overridden the generate method.&nbsp; The parser
always calls generate, but since this is a server-side artifact, we don't
want to generate it unless we are generating server-side artifacts (in
other words, in terms of the command line options, we've specified the
--serverSide option).
<p><tt>public class MyDeployWriter extends JavaWriter {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public MyDeployWriter(Emitter emitter, Definition
definition,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
SymbolTable symbolTable) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(emitter,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
new QName(definition.getTargetNamespace(), "deploy"),</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"", "useless", "Generating deploy.useless", "deploy");</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void generate() throws IOException {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (emitter.isServerSide())
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
super.generate();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void writeFileHeader() throws IOException
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void writeFileBody() throws IOException
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyEmitter myEmitter
= (MyEmitter) emitter;</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (myEmitter.getSong()
== MyEmitter.RUM) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pw.println("Yo!&nbsp; Ho!&nbsp; Ho!&nbsp; And a bottle of rum.");</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (myEmitter.getSong()
== MyEmitter.WORK) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pw.println("Hi ho!&nbsp; Hi ho!&nbsp; It's off to work we go.");</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pw.println("Feelings...&nbsp; Nothing more than feelings...");</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pw.close();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<br><tt></tt>&nbsp;
<li>
Since we're changing what WSDL2Java generates, rather than simply adding
to it like the previous example did, calling addGenerator isn't good enough.&nbsp;
In order to change what WSDL2Java generates, you have to create a generator
factory and provide your own generators.&nbsp; Since we want to keep most
of WSDL2Java's artifacts, we can simply extend WSDL2Java's factory - JavaGeneratorFactory
- and override the addDefinitionGenerators method.</li>

<p><br><tt>public class MyGeneratorFactory extends JavaGeneratorFactory
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void addDefinitionGenerators() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addGenerator(Definition.class,
JavaDefinitionWriter.class); // WSDL2Java's JavaDefinitionWriter</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addGenerator(Definition.class,
MyDeployWriter.class); // our DeployWriter</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addGenerator(Definition.class,
JavaUndeployWriter.class); // WSDL2Java's JavaUndeployWriter</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<br>&nbsp;
<li>
Now we must write the API's to our tool.&nbsp; Since we've added an option
- song - we need both the programmatic API - an extension of Parser (actually
Emitter in this case since we're extending WSDL2Java and Emitter is WSDL2Java's
parser extension) - and the command line API.</li>

<p><br>Here is our programmatic API.&nbsp; It adds song accessors to Emitter.&nbsp;
It also, in the constructor, lets the factory know about the emitter and
the emitter know about the factory.
<p><tt>public class MyEmitter extends Emitter {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public static final int RUM&nbsp; = 0;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public static final int WORK = 1;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; private int song = -1;</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; public MyEmitter() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyGeneratorFactory factory
= new MyGeneratorFactory();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setFactory(factory);</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory.setEmitter(this);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public int getSong() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return song;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void setSong(int song) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.song = song;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<p>And here is our command line API.&nbsp; It's a bit more complex that
our previous example's main program, but it does 2 extra things:
<ol>
<li>
accept a new command line option:&nbsp; --song rum|work (this is the biggest
chunk of the new work).</li>

<li>
create a new subclass of Parser</li>
</ol>

<p><br><tt>public class WSDL2Useless extends WSDL2Java {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected static final int SONG_OPT = 'g';</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected static final CLOptionDescriptor[]
options = new CLOptionDescriptor[]{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new CLOptionDescriptor("song",</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CLOptionDescriptor.ARGUMENT_REQUIRED,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
SONG_OPT,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"Choose a song for deploy.useless:&nbsp; work or rum")</tt>
<br><tt>&nbsp;&nbsp;&nbsp; };</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp; public WSDL2Useless() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addOptions(options);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected Parser createParser() {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new MyEmitter();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; protected void parseOption(CLOption option)
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (option.getId() ==
SONG_OPT) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
String arg = option.getArgument();</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (arg.equals("rum")) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
((MyEmitter) parser).setSong(MyEmitter.RUM);</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
else if (arg.equals("work")) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
((MyEmitter) parser).setSong(MyEmitter.WORK);</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
super.parseOption(option);</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public static void main(String args[]) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WSDL2Useless useless
= new WSDL2Useless();</tt><tt></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useless.run(args);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<p>Let's go through this one method at a time.
<ul>
<li>
constructor - this constructor adds the new option --song rum|work.&nbsp;
(the abbreviated version of this option is "-g", rather an odd abbreviation,
but "-s" is the abbreviation for --serverSide and "-S" is the abbreviation
for --skeletonDeploy.&nbsp; Bummer.&nbsp; I just picked some other letter.</li>

<li>
createParser - we've got to provide a means by which the parent class can
get our Parser extension.</li>

<li>
parseOption - this method processes our new option.&nbsp; If the given
option isn't ours, just let super.parseOption do its work.</li>

<li>
main - this main is actually simpler than the first example's main.&nbsp;
The first main had to add our generator to the list of generators.&nbsp;
In this example, the factory already did that, so all that this main must
do is instantiate itself and run itself.</li>
</ul>
</ul>

<h2>
<a NAME="Client SSL"></a>Client SSL</h2>
The default pluggable secure socket factory module
(see <a href="#Pluggable APIs">Pluggable APIs</a>)
uses JSSE security.
Review the JSSE documentation for details on
installing, registering, and configuring JSSE for your runtime environment.

</body>
</html>